Alumnos del grupo:

Alumno Código Correo Porcentaje de Trabajo
Samir Stefano Suarez Rios 202210611 samir.suarez@utec.edu.pe 100%
Milton Esteban Robles Reyes 202210416 milton.robles@utec.edu.pe 15%
Gabriel Fournier 201610002 **** x%
Karen 201610002 **** x%

Introducción

Tema

Análisis mensual de la relación entre número de pasajeros e ingresos totales por aeropuerto del Perú (2020-2022).

Relevancia

La relevancia de nuestro proyecto se centra en varios aspectos, el mas básico de ellos es el transporte aéreo, que durante mucho tiempo de evolución, ha significado una oportunidad de conexión global, junto a ello, desarrollo económico y social. La delimitación temporal nos permite analizar el impacto crucial de la pandemia de COVID-19, desencadenada en 2020. Al examinar la relación entre el número de pasajeros y los ingresos en diversos rubros, nuestro proyecto ofrece un análisis integral de la salud financiera y rentabilidad de cada aeropuerto estudiado. Además, al considerar la influencia de la pandemia, exploraremos posibles declives o reactivaciones durante el periodo 2020-2022. Esto adquiere gran importancia en el contexto económico del Perú, ya que el turismo es un sector que además de estar muy ligado al transporte aéreo, aporta significativamente a la economía nacional. Nuestro proyecto proporcionará información valiosa para la toma de decisiones en este ámbito.

Objetivo

Evaluar los factores que influyen en los ingresos totales (US$) por mes y año en cada aeropuerto en el Perú.

Objetivo Secundarios

  • Comparar los ingresos totales con los rubros en los aeropuertos del Perú

  • Comparar los ingresos totales con el número de pasajeros en los aeropuertos del Perú evaluando su influencia

  • Determinar el aeropuerto con mayor afluencia de pasajeros y el de mayor ingresos del Perú

  • Comparar los ingresos totales (US$) durante la pandemia y post pandemia en el Perú

Tabla de variables

Librerías

Base de datos

Datos

Tabla de variables

Año: Variable categórica que indica el año de la recolección de información.

Mes: Variable categórica que indica el mes de la recolección de información.

Aeropuerto: Variable cualitativa que indica el aeropuerto del cual se recolecta la información

Infraestructura: Variable cualitativa que indica a que entidad pertenece la infraestructura del aeropuerto del cual se recolecta la información.

IT: Variable cuantitativa que representa los ingresos totales en dolares que ha registrado el aeropuerto

IR: Variable cuantitativa que representa los ingresos regulados en dolares que ha registrado el aeropuerto

TUUAN: Variable cuantitativa que representa el ingreso en dolares que ha generado la TARIFA UNIFICADA POR USO DE AEROPUERTO de tipo nacional.

TUUAN: Variable cuantitativa que representa el ingreso en dolares que ha generado la TARIFA UNIFICADA POR USO DE AEROPUERTO de tipo internacional.

NPI: Variable cuantitativa que representa el numero de pasajeros internacionales que ha registrado el aeropuerto

NPN: Variable cuantitativa que representa el numero de pasajeros nacionales que ha registrado el aeropuerto

IRAD_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por aterrizaje y despegue.

IRAD: Variable cuantitativa que representa el ingreso en dolares del aeropuerto por aterrizaje y despegue.

AADM_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de áreas de mantenimiento.

AADM: Variable cuantitativa que representa el ingreso en dolares por el alquiler de áreas de mantenimiento.

ADEP_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de espacios de publicidad.

ADEP: Variable cuantitativa que representa el ingreso en dolares por el alquiler de espacios de publicidad.

ALC_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de locales comerciales.

ALC: Variable cuantitativa que representa el ingreso en dolares por el alquiler de locales comerciales.

AOOA_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de oficinas de operaciones de aerolíneas.

AOOA: Variable cuantitativa que representa el ingreso en dolares por el alquiler de oficinas de operaciones de aerolíneas.

ADAH_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de almacenes/hangares.

ADAH: Variable cuantitativa que representa el ingreso en dolares por el alquiler de almacenes/hangares.

AEHE_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por la atención en horas extras.

AEHE: Variable cuantitativa que representa el ingreso en dolares por la atención en horas extras.

IREA_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el estacionamiento de aeronaves.

IREA: Variable cuantitativa que representa el ingreso en dolares por el estacionamiento de aeronaves.

IRIF_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por reembolso en ingresos financieros.

IRIF: Variable cuantitativa que representa el ingreso en dolares por reembolso en ingresos financieros.

IRR_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por reembolsos.

IRR: Variable cuantitativa que representa el ingreso en dolares por reembolsos.

NP: Variable cuantitativa que representa el numero de pasajeros totales que ha registrado el aeropuerto.

Creación del Dataframe

Creando el DataFrame a partir de la variable Ingresos Totales (IT)

ITS <- filter(ITS, Año %in% c("2020","2021","2022"))
ITS %>% group_by(Año,Mes,Aeropuerto,Infraestructura) %>% summarise(IT = sum(`Importe por Servicios`)) -> DF

Importante: Se toma en cuenta que al un aeropuerto no declarar un importe de servicios por un tipo de rubro como el alquiler de espacios publicitarios, los ingresos en este rubro serán 0. Para esto crearemos una variable conjunta al rubro de importe que verificará si este ha sido declarado o no, se identificará con el nombre de la variable y un sufijo “_VER”. Pese a que esta operación genera sesgo, al tener un sentido con la realidad se considera que no es significativo.

Uniendo la variable Numero de Pasajeros Internacionales (NPI)

PI <- filter(TP, `Tipo de Pasajero` == "INTERNACIONAL")
PI <- filter(PI,Año %in% c(2020,2021,2022))
PI <- select(PI, -Periodo)
PI <- select(PI, -`Tipo de Pasajero`)
DF <- merge(DF,PI, by = c("Año","Mes","Aeropuerto","Infraestructura"), all = TRUE)
DF <- rename(DF, "NPI" = "Nro Pasajeros")
DF$NPI[is.na(DF$NPI)] <- 0

#Reemplazo de N/A's por 0

Uniendo la variable Numero de Pasajeros Nacionales (NPN)

PN <- filter(TP, `Tipo de Pasajero` == "NACIONAL")
PN <- filter(PN,Año %in% c(2020,2021,2022))
PN <- select(PN, -Periodo)
PN <- select(PN, -`Tipo de Pasajero`)
DF <- merge(DF,PN, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "NPN" = "Nro Pasajeros")
DF$NPN[is.na(DF$NPN)] <- 0

#Reemplazo de N/A's por 0

Uniendo la variable Ingreso Rubro T U U A NACIONAL (TUUAN)

TUUAN <- filter(ITS, `Rubro Ingreso` == "T U U A NACIONAL")
TUUAN <- filter(TUUAN,Año %in% c(2020,2021,2022))
TUUAN <- select(TUUAN, -'Tipo Ingreso')
TUUAN <- select(TUUAN, -'Rubro Ingreso')
TUUAN <- select(TUUAN, -'Periodo')
#Creación de variable de verificación para reemplazo de N/A's
DF <- merge(DF, TUUAN, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "TUUAN_VER" = "Importe por Servicios")
DF <- merge(DF, TUUAN, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "TUUAN" = "Importe por Servicios")
DF$TUUAN_VER[is.na(DF$TUUAN_VER)] <- 0
DF$TUUAN_VER[DF$TUUAN_VER != 0] <- "Si"
DF$TUUAN_VER[DF$TUUAN_VER == "0"] <- "No"
DF$TUUAN[is.na(DF$TUUAN)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso Rubro T U U A INTERNACIONAL (TUUAI)

TUUAI <- filter(ITS, `Rubro Ingreso` == "T U U A INTERNACIONAL")
TUUAI <- filter(TUUAI,Año %in% c(2020,2021,2022))
TUUAI <- select(TUUAI, -'Tipo Ingreso')
TUUAI <- select(TUUAI, -'Rubro Ingreso')
TUUAI <- select(TUUAI, -'Periodo')
DF <- merge(DF, TUUAI, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "TUUAI_VER" = "Importe por Servicios")#Creación de variable de verificación para reemplazo de N/A's
DF <- merge(DF, TUUAI, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "TUUAI" = "Importe por Servicios")

DF$TUUAI_VER[is.na(DF$TUUAI_VER)] <- 0
DF$TUUAI_VER[DF$TUUAI_VER != 0] <- "Si"
DF$TUUAI_VER[DF$TUUAI_VER == "0"] <- "No"
DF$TUUAI[is.na(DF$TUUAI)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso Rubro ATERRIZAJE Y DESPEGUE (IRAD)

IRAD <- filter(ITS, `Rubro Ingreso` == "ATERRIZAJE Y DESPEGUE")
IRAD <- filter(IRAD,Año %in% c(2020,2021,2022))
IRAD <- select(IRAD, -'Tipo Ingreso')
IRAD <- select(IRAD, -'Rubro Ingreso')
IRAD <- select(IRAD, -'Periodo')

DF <- merge(DF, IRAD, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRAD_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's
DF <- merge(DF, IRAD, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRAD" = "Importe por Servicios")

DF$IRAD_VER[is.na(DF$IRAD_VER)] <- 0
DF$IRAD_VER[DF$IRAD_VER != 0] <- "Si"
DF$IRAD_VER[DF$IRAD_VER == "0"] <- "No"
DF$IRAD[is.na(DF$IRAD)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso Rubro ALQUILER AREAS DE MANTENIMIENTO (AADM)

AADM <- filter(ITS, `Rubro Ingreso` == "ALQUILER AREAS DE MANTENIMIENTO")
AADM <- filter(AADM,Año %in% c(2020,2021,2022))
AADM <- select(AADM, -'Tipo Ingreso')
AADM <- select(AADM, -'Rubro Ingreso')
AADM <- select(AADM, -'Periodo')

DF <- merge(DF, AADM, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AADM_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's
DF <- merge(DF, AADM, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AADM" = "Importe por Servicios")

DF$AADM_VER[is.na(DF$AADM_VER)] <- 0
DF$AADM_VER[DF$AADM_VER != 0] <- "Si"
DF$AADM_VER[DF$AADM_VER == "0"] <- "No"
DF$AADM[is.na(DF$AADM)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso ALQUILER DE ESPACIOS PUBLICITARIOS (ADEP)

ADEP <- filter(ITS, `Rubro Ingreso` == "ALQUILER DE ESPACIOS PUBLICITARIOS")
ADEP <- filter(ADEP,Año %in% c(2020,2021,2022))
ADEP <- select(ADEP, -'Tipo Ingreso')
ADEP <- select(ADEP, -'Rubro Ingreso')
ADEP <- select(ADEP, -'Periodo')

DF <- merge(DF, ADEP, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ADEP_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's
DF <- merge(DF, ADEP, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ADEP" = "Importe por Servicios")

DF$ADEP_VER[is.na(DF$ADEP_VER)] <- 0
DF$ADEP_VER[DF$ADEP_VER != 0] <- "Si"
DF$ADEP_VER[DF$ADEP_VER == "0"] <- "No"
DF$ADEP[is.na(DF$ADEP)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso ALQUILER LOCALES COMERCIALES (ALC)

ALC <- filter(ITS, `Rubro Ingreso` == "ALQUILER LOCALES COMERCIALES")
ALC <- filter(ALC,Año %in% c(2020,2021,2022))
ALC <- select(ALC, -'Tipo Ingreso')
ALC <- select(ALC, -'Rubro Ingreso')
ALC <- select(ALC, -'Periodo')

DF <- merge(DF, ALC, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ALC_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, ALC, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ALC" = "Importe por Servicios")

DF$ALC_VER[is.na(DF$ALC_VER)] <- 0
DF$ALC_VER[DF$ALC_VER != 0] <- "Si"
DF$ALC_VER[DF$ALC_VER == "0"] <- "No"
DF$ALC[is.na(DF$ALC)] <- 0
#Reemplazo de N/A's por 0

Uniendo la variable Ingreso Rubro ALQUILER OFICINAS OPERACIONES AEROLÍNEAS (AOOA)

AOOA <- filter(ITS, `Rubro Ingreso` == "ALQUILER OFICINAS OPERACIONES AEROLÍNEAS")
AOOA <- filter(AOOA,Año %in% c(2020,2021,2022))
AOOA <- select(AOOA, -'Tipo Ingreso')
AOOA <- select(AOOA, -'Rubro Ingreso')
AOOA <- select(AOOA, -'Periodo')

DF <- merge(DF, AOOA, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AOOA_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, AOOA, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AOOA" = "Importe por Servicios")
DF$AOOA_VER[is.na(DF$AOOA_VER)] <- 0
DF$AOOA_VER[DF$AOOA_VER != 0] <- "Si"
DF$AOOA_VER[DF$AOOA_VER == "0"] <- "No"
DF$AOOA[is.na(DF$AOOA)] <- 0

Uniendo la variable Ingreso Rubro ALQUILERES DE ALMACEN/HANGAR (ADAH)

ADAH <- filter(ITS, `Rubro Ingreso` == "ALQUILERES DE ALMACEN/HANGAR")
ADAH <- filter(ADAH,Año %in% c(2020,2021,2022))
ADAH <- select(ADAH, -'Tipo Ingreso')
ADAH <- select(ADAH, -'Rubro Ingreso')
ADAH <- select(ADAH, -'Periodo')

DF <- merge(DF, ADAH, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ADAH_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, ADAH, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "ADAH" = "Importe por Servicios")
DF$ADAH_VER[is.na(DF$ADAH_VER)] <- 0
DF$ADAH_VER[DF$ADAH_VER != 0] <- "Si"
DF$ADAH_VER[DF$ADAH_VER == "0"] <- "No"
DF$ADAH[is.na(DF$ADAH)] <- 0

Uniendo la variable Ingreso Rubro ATENCIÓN EN HORAS EXTRAS (AEHE)

AEHE <- filter(ITS, `Rubro Ingreso` == "ATENCIÓN EN HORAS EXTRAS")
AEHE <- filter(AEHE,Año %in% c(2020,2021,2022))
AEHE <- select(AEHE, -'Tipo Ingreso')
AEHE <- select(AEHE, -'Rubro Ingreso')
AEHE <- select(AEHE, -'Periodo')

DF <- merge(DF, AEHE, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AEHE_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, AEHE, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "AEHE" = "Importe por Servicios")
DF$AEHE_VER[is.na(DF$AEHE_VER)] <- 0
DF$AEHE_VER[DF$AEHE_VER != 0] <- "Si"
DF$AEHE_VER[DF$AEHE_VER == "0"] <- "No"
DF$AEHE[is.na(DF$AEHE)] <- 0

Uniendo la variable Ingreso Rubro ESTACIONAMIENTO AERONAVES (IREA)

IREA <- filter(ITS, `Rubro Ingreso` == "ESTACIONAMIENTO AERONAVES")
IREA <- filter(IREA,Año %in% c(2020,2021,2022))
IREA <- select(IREA, -'Tipo Ingreso')
IREA <- select(IREA, -'Rubro Ingreso')
IREA <- select(IREA, -'Periodo')

DF <- merge(DF, IREA, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IREA_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, IREA, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IREA" = "Importe por Servicios")
DF$IREA_VER[is.na(DF$IREA_VER)] <- 0
DF$IREA_VER[DF$IREA_VER != 0] <- "Si"
DF$IREA_VER[DF$IREA_VER == "0"] <- "No"
DF$IREA[is.na(DF$IREA)] <- 0

Uniendo la variable Ingreso Rubro INGRESOS FINANCIEROS (IRIF)

IRIF <- filter(ITS, `Rubro Ingreso` == "INGRESOS FINANCIEROS")
IRIF <- filter(IRIF,Año %in% c(2020,2021,2022))
IRIF <- select(IRIF, -'Tipo Ingreso')
IRIF <- select(IRIF, -'Rubro Ingreso')
IRIF <- select(IRIF, -'Periodo')

DF <- merge(DF, IRIF, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRIF_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, IRIF, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRIF" = "Importe por Servicios")
DF$IRIF_VER[is.na(DF$IRIF_VER)] <- 0
DF$IRIF_VER[DF$IRIF_VER != 0] <- "Si"
DF$IRIF_VER[DF$IRIF_VER == "0"] <- "No"
DF$IRIF[is.na(DF$IRIF)] <- 0

Uniendo la variable Ingreso Rubro REEMBOLSOS (IRR)

IRR <- filter(ITS, `Rubro Ingreso` == "REEMBOLSOS")
IRR <- filter(IRR,Año %in% c(2020,2021,2022))
IRR <- select(IRR, -'Tipo Ingreso')
IRR <- select(IRR, -'Rubro Ingreso')
IRR <- select(IRR, -'Periodo')

IRR <- filter(IRR, `Importe por Servicios` != 0)

DF <- merge(DF, IRR, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRR_VER" = "Importe por Servicios")
#Creación de variable de verificación para reemplazo de N/A's 
DF <- merge(DF, IRR, by = c("Año","Mes","Aeropuerto","Infraestructura"), all=TRUE)
DF <- rename(DF, "IRR" = "Importe por Servicios")
DF$IRR_VER[is.na(DF$IRR_VER)] <- 0
DF$IRR_VER[DF$IRR_VER != 0] <- "Si"
DF$IRR_VER[DF$IRR_VER == "0"] <- "No"
DF$IRR[is.na(DF$IRR)] <- 0

Creando la variable Numero de Pasajeros totales (NP)

DF %>% mutate(NP = NPN + NPI) -> DF
#Numero de pasajeros totales

Organizando el DF

DF$Mes = factor(DF$Mes, levels =c("Enero","Febrero","Marzo","Abril","Mayo","Junio","Julio","Agosto","Setiembre","Octubre","Noviembre","Diciembre"))
DF <- arrange(DF, Año, Mes)

Limpieza de datos

Se considera que en caso no se cuente con el nombre del aeropuerto o su infraestructura (Siempre debe venir acompañada del nombre), la unidad muestral no podrá entrar al análisis pues por ejemplo si nos dicen cuanto gano un aeropuerto desconocido, esto no nos dirá nada y por ello la eliminaremos.


DF$Aeropuerto[DF$Aeropuerto == 'No precisa'] <- NA
DF$Aeropuerto[DF$Aeropuerto == '-'] <- NA
DF$Infraestructura[DF$Infraestructura == '-'] <- NA

DF <- filter(DF, Infraestructura != is.na("Infraestructura") & Aeropuerto != is.na("Aeropuerto"))

Cambiamos los nombres de la variable Infraestructura:


DF %>% mutate("Infraestructura" =
                  ifelse(Infraestructura=="ADP", "Aeropuertos del Perú S.A.",
                  ifelse(Infraestructura=="AAP", "Aeropuertos Andinos del Perú S.A.",
                  ifelse(Infraestructura=="COR", "CORPAC S.A.",
                  ifelse(Infraestructura=="LAP", "Lima Airport Partners S.R.L.",Infraestructura))))) -> DF

Eliminamos las variables temporales:

rm(list = c("AADM","ADAH","ADEP","AEHE","ALC","AOOA","IRAD","IREA","IRIF","IRS","ITS","PI","PN","TP","TUUAI","TUUAN","IRR"))

Finalmente, eliminaremos aquellas observaciones donde existan NA’s. Antes de hacer esto encontramos que la mayoría de aeropuertos de la infraestructura “CORPAC S.A.” no ha reportado sus ingresos totales por lo tanto estaríamos dejando fuera del análisis a estos aeropuertos.

DF <- drop_na(DF)
sum(complete.cases(DF))

Exportando la base de datos

write_csv(DF,"BaseLimpiav2.csv")

Importando la base datos limpia


rm(list = ls())
library(readr)
library(plyr)
library(dplyr)
library(plotly)
library(tidyr)

DF <- read_csv("BaseLimpiav2.csv")

Variables

Año: Variable categórica que indica el año de la recolección de información.

Mes: Variable categórica que indica el mes de la recolección de información.

Aeropuerto: Variable cualitativa que indica el aeropuerto del cual se recolecta la información

Infraestructura: Variable cualitativa que indica en acrónimo a que entidad pertenece la infraestructura del aeropuerto del cual se recolecta la información.

Infraestructura: Variable cualitativa que indica a que entidad pertenece la infraestructura del aeropuerto del cual se recolecta la información.

IT: Variable cuantitativa que representa los ingresos totales en dolares que ha registrado el aeropuerto

IR: Variable cuantitativa que representa los ingresos regulados en dolares que ha registrado el aeropuerto

TUUAN: Variable cuantitativa que representa el ingreso en dolares que ha generado la TARIFA UNIFICADA POR USO DE AEROPUERTO de tipo nacional.

TUUAN: Variable cuantitativa que representa el ingreso en dolares que ha generado la TARIFA UNIFICADA POR USO DE AEROPUERTO de tipo internacional.

NPI: Variable cuantitativa que representa el numero de pasajeros internacionales que ha registrado el aeropuerto

NPN: Variable cuantitativa que representa el numero de pasajeros nacionales que ha registrado el aeropuerto

IRAD_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por aterrizaje y despegue.

IRAD: Variable cuantitativa que representa el ingreso en dolares del aeropuerto por aterrizaje y despegue.

AADM_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de áreas de mantenimiento.

AADM: Variable cuantitativa que representa el ingreso en dolares por el alquiler de áreas de mantenimiento.

ADEP_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de espacios de publicidad.

ADEP: Variable cuantitativa que representa el ingreso en dolares por el alquiler de espacios de publicidad.

ALC_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de locales comerciales.

ALC: Variable cuantitativa que representa el ingreso en dolares por el alquiler de locales comerciales.

AOOA_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de oficinas de operaciones de aerolíneas.

AOOA: Variable cuantitativa que representa el ingreso en dolares por el alquiler de oficinas de operaciones de aerolíneas.

ADAH_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el alquiler de almacenes/hangares.

ADAH: Variable cuantitativa que representa el ingreso en dolares por el alquiler de almacenes/hangares.

AEHE_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por la atención en horas extras.

AEHE: Variable cuantitativa que representa el ingreso en dolares por la atención en horas extras.

IREA_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por el estacionamiento de aeronaves.

IREA: Variable cuantitativa que representa el ingreso en dolares por el estacionamiento de aeronaves.

IRIF_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por reembolso en ingresos financieros.

IRIF: Variable cuantitativa que representa el ingreso en dolares por reembolso en ingresos financieros.

IRR_VER: Variable categórica que representa si el aeropuerto obtiene ingresos por reembolsos.

IRR: Variable cuantitativa que representa el ingreso en dolares por reembolsos.

NP: Variable cuantitativa que representa el numero de pasajeros totales que ha registrado el aeropuerto.

Descriptores Numéricos

cv <- function(x){
    return(sd(x, na.rm=T)/mean(x, na.rm=T))
}
tabla <- data.frame(Variables = c('IT', 'NPN', 'NPI', 'TUUAN','TUUAI'),
                    Media = c(mean(DF$IT, na.rm=T), 
                              mean(DF$NPN, na.rm = T), 
                              mean(DF$NPI, na.rm= T),
                              mean(DF$TUUAN, na.rm= T),
                              mean(DF$TUUAI, na.rm= T)),
                    
                    Mediana = c(median(DF$IT, na.rm=T), 
                                median(DF$NPN, na.rm = T), 
                                median(DF$NPI, na.rm= T),
                                median(DF$TUUAN, na.rm = T), 
                                median(DF$TUUAI, na.rm= T)), 
                    
                    Desviacion = c(sd(DF$IT, na.rm=T), 
                                   sd(DF$NPN, na.rm = T), 
                                   sd(DF$NPI, na.rm= T), 
                                   sd(DF$TUUAN, na.rm = T), 
                                   sd(DF$TUUAI, na.rm= T)), 
                    
                    Varianza = c(var(DF$IT, na.rm = T), 
                                 var(DF$NPN, na.rm = T), 
                                 var(DF$NPI, na.rm = T), 
                                 var(DF$TUUAN, na.rm = T), 
                                 var(DF$TUUAI, na.rm = T)),
                    
                    RangoIntercuartil = c(IQR(DF$IT, na.rm = T), 
                                        IQR(DF$NPN, na.rm = T), 
                                        IQR(DF$NPI, na.rm = T), 
                                        IQR(DF$TUUAN, na.rm = T), 
                                        IQR(DF$TUUAI, na.rm = T)),
                    
                    CoeficienteVariacion = c(cv(DF$IT), 
                                 cv(DF$NPN), 
                                 cv(DF$NPI),
                                 cv(DF$NPN), 
                                 cv(DF$NPI)))
tabla

De la tabla podemos conseguir la siguiente información:

  • La escala con la que se trabaja es bastante grande, de ahí el hecho que la varianza y desviación sean tan grande.

  • Tanto la varianza como la desviación nos indican que los datos de los Ingresos Totales, el Numero de Pasajeros Nacionales y el Numero de Pasajeros Internacionales están muy dispersos.

  • Se aprecia un fenómeno que la mediana y el rango intercuartil de la variable Pasajeros internacionales es 0. Esto quiere decir que hay muchos aeropuertos los cuales no suelen recibir pasajeros internacionales.

Objetivo 1

Se realizara el coeficiente de correlación entre cada variable rubro y los ingresos totales, además se creará un modelo lineal que represente las relaciones. Esto nos facilita el trabajar con las 12 variables y poder sintetizar la información en un solo gráfico.

coefcor <- c(1:12)

# TUUAN 
coefcor[1] <-cor(DF$IT, DF$TUUAN, use="complete.obs")

# TUUAI
coefcor[2] <-cor(DF$IT, DF$TUUAI, use="complete.obs")

# IRAD
coefcor[3] <-cor(DF$IT, DF$IRAD, use="complete.obs")


# AADM
coefcor[4] <-cor(DF$IT, DF$AADM, use="complete.obs")

# ADEP
coefcor[5] <-cor(DF$IT, DF$ADEP, use="complete.obs")

# ALC
coefcor[6] <-cor(DF$IT, DF$ALC, use="complete.obs")

# AOOA
coefcor[7] <-cor(DF$IT, DF$AOOA, use="complete.obs")


# ADAH
coefcor[8] <-cor(DF$IT, DF$ADAH, use="complete.obs")

# AEHE
coefcor[9] <-cor(DF$IT, DF$AEHE, use="complete.obs")


# IREA
coefcor[10] <-cor(DF$IT, DF$IREA, use="complete.obs")

# IRIF
coefcor[11] <-cor(DF$IT, DF$IRIF, use="complete.obs")

# IRR
coefcor[12] <-cor(DF$IT, DF$IRR, use="complete.obs")

Ahora se procederá a la revisión de los coeficientes de correlación, si estos tienen un número mayor a 0.75 o menor a -0.75 se considerará que tienen un modelo lineal válido.

coefcor

Se observa que los coeficientes de correlación con indices (4, 5, 6, 7, 8, 9, 11 y 12) no cumplen con el criterio requerido, es decir no poseen una correlación lineal con la variable de ingresos totales, esto también nos indica que sus datos se encuentran muy dispersos en comparación con los datos de los ingresos totales.

Ahora se realizará y graficará los modelos lineales de la variables que presentan buena correlación. Es importante notar que en todas estas se tiene una correlación positiva, esto tiene sentido pues entre más dinero haya de algún rubro, más dinero habrá en los ingresos totales


pendientes <- c(1:4)
interceptos <- c(1:4)

# TUUAN 
modelo <- lm(DF$IT ~ DF$TUUAN, data=DF)
pendientes[1] <- as.numeric(modelo$coefficients[2])
interceptos[1] <- as.numeric(modelo$coefficients[1])


# TUUAI
modelo <- lm(DF$IT ~ DF$TUUAI, data=DF)
pendientes[2] <- as.numeric(modelo$coefficients[2])
interceptos[2] <- as.numeric(modelo$coefficients[1])


# IRAD
modelo <- lm(DF$IT ~ DF$IRAD, data=DF)
pendientes[3] <- as.numeric(modelo$coefficients[2])
interceptos[3] <- as.numeric(modelo$coefficients[1])

# IRIF
modelo <- lm(DF$IT ~ DF$IREA, data=DF)
pendientes[4] <- as.numeric(modelo$coefficients[2])
interceptos[4] <- as.numeric(modelo$coefficients[1])
fig <- plot_ly(DF, x = ~TUUAN, y = ~IT, 
               type = "scatter", 
               mode = "markers",
               name="TUUAN",
               marker = list(color = '#ef476f')
               ) %>%
        add_trace(x = ~c(-interceptos[1]/pendientes[1],9000000), y = c(0,pendientes[1]*9000000+interceptos[1]), 
               type = "scatter",
               mode = "lines",
               name="TUUAN-model",
               marker = list(color = '#ef476f')
               ) %>%
        add_trace(DF, x = ~TUUAI, y = ~IT, 
                  type = "scatter", 
                  mode = "markers",
                  name="TUUAI",
                  marker = list(color = '#ffd166')
                  ) %>%
        add_trace(x = ~c(-interceptos[2]/pendientes[2],9000000), y = c(0,pendientes[2]*9000000+interceptos[2]), 
                  type = "scatter", 
                  mode = "lines",
                  name="TUUAI-model",
                  marker = list(color = '#ffd166')
                  ) %>%
        add_trace(DF, x = ~IRAD, y = ~IT, 
                  type = "scatter", 
                  mode = "markers",
                  name="IRAD",
                  marker = list(color = '#06d6a0')
                  ) %>%
        add_trace(x = ~c(-interceptos[3]/pendientes[3],9000000), y = c(0,pendientes[3]*9000000+interceptos[3]), 
                  type = "scatter", 
                  mode = "lines",
                  name="IRAD-model",
                  marker = list(color = '#06d6a0')
                  ) %>%
        add_trace(DF, x= ~IREA, y = ~IT, 
                  type="scatter", 
                  mode="markers",
                  name="IREA",
                  marker = list(color = '#118ab2')
                  ) %>%
        add_trace(x = ~c(-interceptos[4]/pendientes[4],9000000), y = c(0,pendientes[4]*9000000+interceptos[4]), 
                  type="scatter", 
                  mode="lines",
                  name="IREA-model",
                  marker = list(color = '#118ab2')
                  ) %>%
        layout(xaxis = list( title = "Ingresos US$"),
        yaxis = list( title = "Ingresos totales US$"))


fig
    

Usando el gráfico interactivo podemos aislar cada uno de estos rubros y ver su comportamiento junto a su modelo. Aquí vemos como el modelo de IREA tiene la mayor pendiente significando que la mayor parte de los ingresos totales en proporción vendría de este rubro, sin embargo, observamos que la data no es congruente, el modelo no se aproxima correctamente pese a que vimos que obtuvo un coeficiente de correlación mayor a 0.75. Con esto se deja en evidencia que el coeficiente de correlación lineal no es el único que debemos tomar en cuenta al realizar un modelo de regresión lineal. Entonces, dejando de lado a IREA, se aprecia que los modelos y la data de TUUAN, TUUAI e IRAD se aproximan bastante bien, siendo, el de mayor pendiente, IRAD. Por lo que concluimos que la mayor parte de los ingresos totales dependen de los ingresos obtenidos por el importe de servicios de Aterizaje y despegue.

Objetivo 2


plot(DF$IREA, DF$IT, xlab = "Numero de pasajeros (miles)", ylab = "Ingresos totales (millones de US$)", col="darkgreen", pch="•")
abline(a=interceptos[4], b= pendientes[4])
plot_ly(y =~ DF$IT, x =~DF$IREA, type="scatter") %>%
    

Numero de Pasajeros vs Ingresos Totales

plot(DF$NP/1000, DF$IT/1000000, xlab = "Numero de pasajeros (miles)", ylab = "Ingresos totales (millones de US$)", col="darkgreen", pch="•", xlim = c(0,2000))

Comenzamos comparando el numero de pasajeros en miles totales, suma de pasajeros internacionales y nacionales, con los ingresos totales de cada aeropuerto en determinado mes y año en millones de dolares. A simple vista se puede ver un cierto tipo de relación lineal, sin embargo tenemos que comprobarlo. Usaremos el coeficiente de correlación ya que este no toma en cuenta la escala de las unidades, perfecto para nuestro estudio.

cor(DF$IT, DF$NP, use="complete.obs")

Con la información suministrada del coeficiente de correlación se deduce que la relación lineal entre el numero de pasajeros y los ingresos totales es buena, casi perfecta y ascendente. Es decir los ingresos totales aumentaran en cuanto aumente el numero de pasajeros.

Ahora crearemos un modelo de regresión lineal.


modelo = lm(DF$IT ~ DF$NP, data=DF)
modelo

d <- data.frame("X"=DF$NP/1000, "Y"=DF$IT/1000000)
modelo = lm(d$Y ~ d$X, data=d)
modelo

Hemos creado dos modelos que en realidad son el mismo pero a diferentes escalas. El primero nos sirve para usar directamente el numero de pasajeros y los ingresos totales en dolares. El segundo para usar el numero de pasajeros en miles y conseguir los ingresos totales en millones de dolares. Ambos modelos nos permiten aproximar, predecir los ingresos totales de un aeropuerto en determinado mes y año usando la cantidad de pasajeros totales que llevo en el mismo lapso de tiempo.

plot(DF$NP/1000, DF$IT/1000000, xlab = "Numero de pasajeros (miles)", ylab = "Ingresos totales (millones de US$)", col="darkgreen", pch="•", xlim = c(0,2000))
abline(a= -0.14890, b=0.01646, col="green")

Numero de Pasajeros Nacionales e Internacionales vs Ingresos Totales

par(mfrow=c(1,2))

plot(DF$NPN/1000, DF$IT/1000000, xlab = "Numero de pasajeros nacionales (miles)", ylab = "Ingresos totales (millones de US$)", col="red", pch="•")

plot(DF$NPI/1000, DF$IT/1000000, xlab = "Numero de pasajeros internacionales (miles)", ylab = "Ingresos totales (millones de US$)", col="blue", pch="•")

Ahora vamos a analizar la relación de los tipos de pasajeros con los ingresos totales. De nuevo usaremos el coeficiente de correlación tanto para los pasajeros nacionales como internacionales.

cor(DF$IT, DF$NPN, use="complete.obs")
cor(DF$IT, DF$NPI, use="complete.obs")

De los coeficientes dados se encuentra que:

  • Ambos demuestran que tanto los pasajeros nacionales como internacionales poseen una buena y ascendente relación lineal con los ingresos totales.
  • Ambos son menores al cor de los pasajeros totales con los ingresos totales. Indica que si se usa solo a los pasajeros nacionales o solo a los internacionales para aproximar los ingresos totales, se tendrá una precisión menor a que si se usará la suma de ambos.
  • El cor de los pasajeros internacionales es ligeramente superior al de los pasajeros nacionales, mostrando que su relación lineal con los ingresos totales es ligeramente más acorde que la relación lineal de los pasajeros nacionales.

Ahora construyamos los modelos de regresión lineal para cada uno.


modelo = lm(DF$IT ~ DF$NPN, data=DF)
modelo

d <- data.frame("X"=DF$NPN/1000, "Y"=DF$IT/1000000)
modelo = lm(d$Y ~ d$X, data=d)
modelo

modelo = lm(DF$IT ~ DF$NPI, data=DF)
modelo

d <- data.frame("X"=DF$NPI/1000, "Y"=DF$IT/1000000)
modelo = lm(d$Y ~ d$X, data=d)
modelo

rm(d)

Vemos que los modelos difieren en una cantidad considerable en cuanto a su pendiente, sin embargo, su intercepto es bastante similar, vamos a graficar estos modelos.

par(mfrow=c(1,2))

plot(DF$NPN/1000, DF$IT/1000000, xlab = "Numero de pasajeros nacionales (miles)", ylab = "Ingresos totales (millones de US$)", col="red", pch="•")
abline(a= -0.36033, b=0.02451, col="#f72585")

plot(DF$NPI/1000, DF$IT/1000000, xlab = "Numero de pasajeros internacionales (miles)", ylab = "Ingresos totales (millones de US$)", col="blue", pch="•")
abline(a= 0.31996, b=0.04772, col="#0077b6")

Objetivo 3

Para averiguar cual es el aeropuerto que mayor tráfico y el aeropuerto que mayores ingresos genera en el Perú en los años (2020, 2021 y 2022), analizaremos la distribución de Ingresos Totales planteando gráficos y relaciones.

Analizando la distribución de Ingresos Totales

plot_ly(x = ~DF$IT/1000000,
        type="histogram",
        color = ~DF$Infraestructura,
        nbinsx = 40
        )%>%
layout(yaxis = list( title = "Frecuencia" ),
    xaxis = list( title = "Ingresos totales (Millones de US$)",
                  nticks = 20))

Gracias al histograma se dice que los datos de los ingresos totales son totalmente asimétricos y se encuentran acumulados en un intervalo de 0 - 0.8 millones de dolares. Es decir la mayoría de aeropuertos determinados en cierto mes y cierto año posee unos ingresos totales de entre 0 y 0.8 millones de dolares. Esto puede ocurrir debido a datos atípicos, construyamos un Boxplot para que nos ayude.

plot_ly(DF, x=~DF$IT/1000000,
            type = "box")%>%
layout(
    xaxis = list( title = "Ingresos totales (Millones de US$)"))

Usando un Boxplot simple se comprueba como los datos de los ingresos totales están demasiado dispersos gracias a cierta cantidad de datos atípicos. Ahora es necesario averiguar de donde provienen estos datos atípicos y que nos quieren decir. Para ello crearemos diferentes Boxplots basados en meses, infraestructuras y aeropuertos.

plot_ly(DF, x = ~IT/1000000, 
        y = ~Mes, 
        color= ~Mes, 
        type="box") %>%
layout(yaxis = list( title = "Mes"),
    xaxis = list( title = "Ingresos totales (Millones de US$)"))
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Con este gráfico podemos descartar que los datos atípicos provengan de un o varios meses en específico.

plot_ly(DF, x = ~IT/1000000, 
        y = ~Infraestructura, 
        color= ~Infraestructura, 
        type="box") %>%
layout(yaxis = list( title = "Infraestructura"),
    xaxis = list( title = "Ingresos totales (Millones de US$)"))

En este gráfico se observa como Lima Airport Partners S.R.L rebasa por mucho a las otras infraestructuras en cuanto a ingresos totales se refiere. Aquí podemos ya saber que esos datos atípicos de ingresos están generados en su gran mayoría por la infraestructura Lima Airport Partners S.R.L. Además es importante mencionar que la infraestructura COR no aparece en la gráfica pues no ha declarado ningún ingreso total.

Otros datos a considerar:

  • El boxplot de Lima Airport Partners S.R.L se ve perfecto cuando lo aislamos, muestra que no posee ningún dato atípico.

  • El boxplot de Aeropuertos del Perú S.A al aislarlo se observa como la caja es bastante pequeña y posee muchos datos atípicos que son mayores a la mediana.

  • El boxplot de Aeropuertos Andinos del Perú S.A muestra un bigote pegado al cuartil 25%, demostrando que los datos del 25% inferior son iguales o muy cercanos. Asimismo se observan datos atipicos mayores a la mediana.

plot_ly(DF, x = ~IT/1000000, 
        y = ~Aeropuerto, 
        color= ~Aeropuerto, 
        type="box"
        ) %>%
layout(yaxis = list( title = "Aeropuertos"),
    xaxis = list( title = "Ingresos totales (Millones de US$)"))
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors
Warning: n too large, allowed maximum for palette Set2 is 8
Returning the palette you asked for with that many colors

Gracias a los 3 gráficos podemos concluir que:

  • El aeropuerto de Lima cuya entidad prestadora es la LAP, es la responsable de los datos atípicos y además es el que más ingresos totales genera.

  • El boxplot del aeropuerto Lima aislado en base a los ingresos totales muestra que existe datos menores a la mediana más sin embargo su minimo se apróxima por mucho al quartil inferior 25%.

  • La infraestructura LAP trabaja en Lima y se refiere al Aeropuerto Internacional Jorge Chávez. Esto nos quiere decir que en el Perú, el aeropuerto que genera más ingresos es el Jorge Chávez.

Numero de Pasajeros vs Aeropuertos

plot_ly(DF,y = ~NP/1000,
        x = ~as.factor(Aeropuerto), 
        type="bar",
        marker = list(color=c("lightblue"))
        )%>%
    layout(xaxis = list( title = "Aeropuertos"),
    yaxis = list( title = "Numero de pasajeros (miles)"))

Con esta gráfico se corrobora que el Aeropuerto de Lima (Aeropuerto Internacional Jorge Chávez) genera la mayor cantidad de ingresos y además recibe a la mayor cantidad de pasajeros respecto al resto del Perú. Otros aeropuertos notables son Cusco, Arequipa e Iquitos donde Cusco es el que más pasajeros recibe fuera de Lima. Se procede a dibujar el numero de pasajeros, los ingresos totales y los aeropuertos.

plot_ly(DF,x = ~NP/1000,
        y = ~IT/1000000, 
        type="scatter",
        color = ~as.factor(Aeropuerto)
        )

El gráfico nos deja en claro la estrecha relación de la cantidad de pasajeros con la de ingresos que posee el aeropuerto de Lima y como este sobresale por mucho del resto de aeropuertos. Se concluye que los datos atípicos provenientes de ingresos totales eran y nos contaban sobre las peculiaridades del caso Lima.

Ingresos T U U A Total vs Ingresos Totales

Se eligió la comparación de las T U U A, porque esta es la TARIFA UNIFICADA POR USO DE AEROPUERTO, es decir es una tarifa que como consumidores debemos de pagar. El objetivo aquí es analizar cuanto de los ingresos totales provienen directamente de los bolsillos de los pasajeros.

plot((DF$TUUAN/1000000 + DF$TUUAI/1000000), DF$IT/1000000, xlab = "Ingresos TUUA (millones de US$)", ylab = "Ingresos totales (millones de US$)", col="#926c15", pch="•")

Comenzamos comparando el numero de pasajeros en miles totales, suma de pasajeros internacionales y nacionales, con los ingresos totales de cada aeropuerto en determinado mes y año en millones de dolares. A simple vista se puede ver un cierto tipo de relación lineal, sin embargo tenemos que comprobarlo. Usaremos el coeficiente de correlación ya que este no toma en cuenta la escala de las unidades, perfecto para nuestro estudio.

cor(DF$IT, DF$TUUAI + DF$TUUAN, use="complete.obs")

Tenemos un coeficiente de correlación que esta muy próximo a 1, es decir esta relación es casi perfectamente lineal y con tendencia ascendente.

Ahora crearemos un modelo de regresión lineal.

TUUA <- DF$TUUAI+DF$TUUAN
modelo = lm(DF$IT ~ TUUA, data=DF)
modelo

Call:
lm(formula = DF$IT ~ TUUA, data = DF)

Coefficients:
(Intercept)         TUUA  
  155740.38         2.19  
d <- data.frame("X"= (DF$TUUAI + DF$TUUAN)/100000, "Y"=DF$IT/1000000)
modelo = lm(d$Y ~ d$X, data=d)
modelo

Call:
lm(formula = d$Y ~ d$X, data = d)

Coefficients:
(Intercept)          d$X  
     0.1557       0.2190  
rm(d)

Del modelo creado se obtiene el intercepto, es decir cuando la TUUA valdrá cero y la pendiente, en este caso es relativamente baja pero ascendente.

plot((DF$TUUAN+DF$TUUAI)/100000, DF$IT/1000000, xlab = "Ingresos TUUA total (millones de US$)", ylab = "Ingresos totales (millones de US$)", col="#926c15", pch="•")
abline(a= 0.1557, b=0.2190, col="#c9a227")

Detallamos entonces que los ingresos totales guardan una alta relación con los ingresos generados por las TUUA y dependen en gran medida de estas, ergo la cantidad de pasajeros.

Objetivo 4

Ahora haremos un análisis de la pandemia y postpandemia de los ingresos totales en los aeropuertos del Perú en los años (2020,2021 y 2022)

Pandemia vs PostPandemia

DF2020 <- filter(DF, DF$Año=="2020")
DF2021 <- filter(DF, DF$Año=="2021")
DF2022 <- filter(DF, DF$Año=="2022")

DF2020 %>% group_by(Mes,Año) %>% summarise(IT = sum(IT, na.rm=TRUE), NP = sum(NP, na.rm = TRUE)) -> DF2020

DF2021 %>% group_by(Mes,Año) %>% summarise(IT = sum(IT, na.rm=TRUE), NP = sum(NP, na.rm = TRUE)) -> DF2021
                                           
DF2022 %>% group_by(Mes,Año) %>% summarise(IT = sum(IT, na.rm=TRUE), NP = sum(NP, na.rm = TRUE)) -> DF2022
plot_ly(y = ~DF2020$IT/1000000,
        x = ~DF2020$Mes, 
        type="bar",
        name="2020",
        marker = list(color = '#57cc99')
        )%>% 

    
    add_trace(y = ~DF2021$IT/1000000,
        x = ~DF2021$Mes, 
        type="bar",
        name="2021",
        marker = list(color = '#38a3a5')
        )%>%
    
    
    add_trace(y = ~DF2022$IT/1000000,
        x = ~DF2022$Mes, 
        type="bar",
        name="2022",
        marker = list(color = '#22577a')
        )%>%
    
    
    layout(xaxis = list( title = "Meses"),
    yaxis = list( title = "Ingresos totales (Millones de US$)",
    nticks = 10,
    range = list(0,45)),
    
    barmode="group")

Del gráfico de barras podemos observar:

  • La distribución de los ingresos totales en base a los meses del año.

  • Existe una asimetria notable entre los datos en el año 2020. Esta asimetria se explica por el surgimiento del Covid-19. Los ingresos bajaron bastante en proporción a la media.

  • Un patrón de crecimiento sobre los ingresos totales dependiendo de los meses. En algunos meses los ingresos totales son esperado a ser mayores que en otros meses, uno de los factores que pueden influir en esto son las vacaciones pues están estrechamente relacionas con el número de pasajeros a abordar en un aeropuerto.


plot_ly() %>%
    add_trace(y = ~DF2020$IT/1000000,
        x = ~DF2020$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2020",
        marker = list(color = '#57cc99'),
        line = list(color = '#57cc99'),
        fill = "tonexty",
        fillcolor = 'rgba(197,237,211,0.3)'
        )%>%
    add_trace(DF2021, y = ~DF2021$IT/1000000,
        x = ~DF2021$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2021",
        marker = list(color = '#38a3a5'),
        line = list(color = '#38a3a5'),
        fill = "tonexty",
        fillcolor = 'rgba(106,166,169,0.3)'
        )%>%
    add_trace(y = ~DF2022$IT/1000000,
        x = ~DF2022$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2022",
        marker = list(color = '#22577a'),
        line = list(color = '#22577a'),
        fill = "tonexty",
        fillcolor = 'rgba(68,102,122,0.3)'
        )%>%
    
    layout(xaxis = list( title = "Meses"),
           title = "Evolutivo Ingresos",
    yaxis = list( title = "Ingresos totales (Millones de US$)", 
                  range = list(0,45))
    )
NA
plot_ly() %>%
    add_trace(y = ~DF2020$NP/1000,
        x = ~DF2020$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2020",
        marker = list(color = '#E09F3E'),
        line = list(color = '#E09F3E'),
        fill = "tonexty",
        fillcolor = 'rgba(225,183,123,0.3)'
        )%>%
    add_trace(DF2021, y = ~DF2021$NP/1000,
        x = ~DF2021$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2021",
        marker = list(color = '#9E2A2B'),
        line = list(color = '#9E2A2B'),
        fill = "tonexty",
        fillcolor = 'rgba(158,72,74,0.3)'
        )%>%
    add_trace(y = ~DF2022$NP/1000,
        x = ~DF2022$Mes, 
        type="scatter",
        mode="lines+markers",
        name="2022",
        marker = list(color = '#540B0E'),
        line = list(color = '#540B0E'),
        fill = "tonexty",
        fillcolor = 'rgba(87,45,47,0.3)'
        )%>%
    
    layout(xaxis = list( title = "Meses"),
           title = "Evolutivo Pasajeros",
    yaxis = list( title = "Numero de Pasajeros (Miles)"))

De los gráficos evolutivos podemos apreciar:

  • Como es el comportamiento de los ingresos totales frente a los meses y a los años marcados por la pandemia.

  • En el mes de Febrero del año 2020 comienza una caída drástica en los ingresos hasta Abril del mismo año donde comienza a estabilizarse. Este periodo coincide con la aparición del Covid-19 en Perú y el establecimiento de las medidas de confinamiento. El confinamiento indica que el número de pasajeros se reduce en gran proporción. Esta causa también se puede observar en el evolutivo de pasajeros y el como su número de cae hasta 0 o casi 0. Los aeropuerto tuvieron consecuencias que tardaron mucho en disiparse Muestra de ello es como se tardó 2 años y 5 meses para volver a un punto similar al de Febrero 2020 en ingresos totales.

```r

round(100 - ((filter(DF2020, Mes == "Abril")$IT/1000000 )/( filter(DF2020, Mes == "Febrero")$IT/1000000) * 100) ,2)
```
```
[1] 86.68
```
```r
round( - filter(DF2020, Mes == "Abril")$IT/1000000  + filter(DF2020,Mes == "Febrero")$IT/1000000, 2)
```
```
[1] 31.67
```
  • La pérdida del mes de Abril del 2020 respecto al mes de Febrero del 2020 fue del 86.68% suponiendo una diferencia de 31.76 millones de dolares.

  • A partir del mes de Abril se estabilizan los ingresos del año 2020. Estos son bajos pero se observa una tendencia ascendente. Tendencia que continua en los años 2021 y 2022 a medida que el confinamiento se levanta, la pandemia se controla y el numero de pasajeros aumenta.

Conclusión

A razón de resumen, en nuestro análisis sobre los factores influyentes en los ingresos totales de los aeropuertos se gráfico la distribución de los ingresos totales, las diferentes relaciones entre variables tales como la última vista (Ingresos TUUA vs Ingresos Totales), (cantidad de pasajeros y aeropuertos). Asimismo observamos y describimos el comportamiento evolutivo de los ingresos totales respecto a los años vividos en pandemia y pos-pandemia. Finalmente, con la información recolectada y el estudio realizado se encontró que los ingresos totales generados por los aeropuertos en el Perú dependen altamente en los consumidores o pasajeros, siendo la TUUA y el IRAD los ejemplos más claros de ello.

Referencias

Gabriel UTEC: OSITRAN DATA. (s/f). Gob.pe:8443. Recuperado el 17 de abril de 2023, de https://serviciosdigitales.ositran.gob.pe:8443/PortalDatosOsitran/inicio.jsp

Meza Juárez, V. A. (2020). APAVIT y turismo seguro post pandemia del Covid-19 [Trabajo de suficiencia profesional para optar el Título Profesional de Licenciado en Comunicación, Universidad de Lima]. Repositorio Institucional. https://hdl.handle.net/20.500.12724/11810

Cubillos, G., & Alejandra, M. (2022). Análisis de la Apertura de la Economía Post Pandemia en los Países Miembros de la Alianza del Pacífico (2020-2021). http://repository.unipiloto.edu.co/handle/20.500.12277/11980

V., Castro Sánchez, F., & Romero Fernández, A. R. F. (2020). Impacto de la COVID-19 en el turismo mundial (Impact of COVID-19 on World Tourism). https://papers.ssrn.com/abstract=3818685

LS0tDQp0aXRsZTogIkVzdGFkaXN0aWNhcyBzb2JyZSBsb3MgYWVyb3B1ZXJ0b3MiDQphdXRob3I6ICJHcnVwbyA3LCBTZWNjacOzbiA5Ig0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJWQgJUIsICVZJylgIg0KZWRpdG9yOiB2aXN1YWwNCmZvcm1hdDogaHRtbA0Kb3V0cHV0Og0KICBodG1sX25vdGVib29rOg0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICAgICAgc21vb3RoX3Njcm9sbDogeWVzDQogICAgbnVtYmVyX3NlY3Rpb25zOiBubw0KICAgIHRvY19kZXB0aDogMg0KDQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCiAgICBkZl9wcmludDogcGFnZWQNCi0tLQ0KDQojICoqQWx1bW5vcyBkZWwgZ3J1cG86KioNCg0KfCBBbHVtbm8gICAgICAgICAgICAgICAgICAgICAgICAgIHwgKipDw7NkaWdvKiogICAgfCAqKkNvcnJlbyoqICAgICAgICAgICAgICAgICAgICAgfCAqKlBvcmNlbnRhamUgZGUgVHJhYmFqbyoqIHwNCnwtLS0tLS0tLS0tLS0tLS0tLS0tLXwtLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfA0KfCAqKipTYW1pciBTdGVmYW5vIFN1YXJleiBSaW9zKioqIHwgKioyMDIyMTA2MTEqKiB8ICoqc2FtaXIuc3VhcmV6XEB1dGVjLmVkdS5wZSoqICB8ICoqMTAwJSoqICAgICAgICAgICAgICAgICAgICB8DQp8ICoqTWlsdG9uIEVzdGViYW4gUm9ibGVzIFJleWVzKiogfCAqKjIwMjIxMDQxNioqIHwgKiptaWx0b24ucm9ibGVzXEB1dGVjLmVkdS5wZSoqIHwgKioxNSUqKiAgICAgICAgICAgICAgICAgICAgfA0KfCAqKkdhYnJpZWwgRm91cm5pZXIqKiAgICAgICAgICAgfCAqKjIwMTYxMDAwMioqIHwgKioqKiB8ICoqeCUqKiAgICAgICAgICAgICAgICAgICAgfA0KfCAqKkthcmVuKiogICB8ICoqMjAxNjEwMDAyKiogfCAqKioqIHwgKip4JSoqICAgICAgICAgICAgICAgICAgICB8DQoNCg0KIyAqKkludHJvZHVjY2nDs24qKg0KDQojIyBUZW1hDQoNCkFuw6FsaXNpcyBtZW5zdWFsIGRlIGxhIHJlbGFjacOzbiBlbnRyZSBuw7ptZXJvIGRlIHBhc2FqZXJvcyBlIGluZ3Jlc29zIHRvdGFsZXMgcG9yIGFlcm9wdWVydG8gZGVsIFBlcsO6ICgyMDIwLTIwMjIpLg0KDQojIyBSZWxldmFuY2lhDQoNCkxhIHJlbGV2YW5jaWEgZGUgbnVlc3RybyBwcm95ZWN0byBzZSBjZW50cmEgZW4gdmFyaW9zIGFzcGVjdG9zLCBlbCBtYXMgYsOhc2ljbyBkZSBlbGxvcyBlcyBlbCB0cmFuc3BvcnRlIGHDqXJlbywgcXVlIGR1cmFudGUgbXVjaG8gdGllbXBvIGRlIGV2b2x1Y2nDs24sIGhhIHNpZ25pZmljYWRvIHVuYSBvcG9ydHVuaWRhZCBkZSBjb25leGnDs24gZ2xvYmFsLCBqdW50byBhIGVsbG8sIGRlc2Fycm9sbG8gZWNvbsOzbWljbyB5IHNvY2lhbC4gTGEgZGVsaW1pdGFjacOzbiB0ZW1wb3JhbCBub3MgcGVybWl0ZSBhbmFsaXphciBlbCBpbXBhY3RvIGNydWNpYWwgZGUgbGEgcGFuZGVtaWEgZGUgQ09WSUQtMTksIGRlc2VuY2FkZW5hZGEgZW4gMjAyMC4gQWwgZXhhbWluYXIgbGEgcmVsYWNpw7NuIGVudHJlIGVsIG7Dum1lcm8gZGUgcGFzYWplcm9zIHkgbG9zIGluZ3Jlc29zIGVuIGRpdmVyc29zIHJ1YnJvcywgbnVlc3RybyBwcm95ZWN0byBvZnJlY2UgdW4gYW7DoWxpc2lzIGludGVncmFsIGRlIGxhIHNhbHVkIGZpbmFuY2llcmEgeSByZW50YWJpbGlkYWQgZGUgY2FkYSBhZXJvcHVlcnRvIGVzdHVkaWFkby4gQWRlbcOhcywgYWwgY29uc2lkZXJhciBsYSBpbmZsdWVuY2lhIGRlIGxhIHBhbmRlbWlhLCBleHBsb3JhcmVtb3MgcG9zaWJsZXMgZGVjbGl2ZXMgbyByZWFjdGl2YWNpb25lcyBkdXJhbnRlIGVsIHBlcmlvZG8gMjAyMC0yMDIyLiBFc3RvIGFkcXVpZXJlIGdyYW4gaW1wb3J0YW5jaWEgZW4gZWwgY29udGV4dG8gZWNvbsOzbWljbyBkZWwgUGVyw7osIHlhIHF1ZSBlbCB0dXJpc21vIGVzIHVuIHNlY3RvciBxdWUgYWRlbcOhcyBkZSBlc3RhciBtdXkgbGlnYWRvIGFsIHRyYW5zcG9ydGUgYcOpcmVvLCBhcG9ydGEgc2lnbmlmaWNhdGl2YW1lbnRlIGEgbGEgZWNvbm9tw61hIG5hY2lvbmFsLiBOdWVzdHJvIHByb3llY3RvIHByb3BvcmNpb25hcsOhIGluZm9ybWFjacOzbiB2YWxpb3NhIHBhcmEgbGEgdG9tYSBkZSBkZWNpc2lvbmVzIGVuIGVzdGUgw6FtYml0by4NCg0KDQojICoqT2JqZXRpdm8qKg0KDQpFdmFsdWFyIGxvcyBmYWN0b3JlcyBxdWUgaW5mbHV5ZW4gZW4gbG9zIGluZ3Jlc29zIHRvdGFsZXMgKFVTJCkgcG9yIG1lcyB5IGHDsW8gZW4gY2FkYSBhZXJvcHVlcnRvIGVuIGVsIFBlcsO6Lg0KDQojIyBPYmpldGl2byBTZWN1bmRhcmlvcw0KDQotICAgQ29tcGFyYXIgbG9zIGluZ3Jlc29zIHRvdGFsZXMgY29uIGxvcyBydWJyb3MgZW4gbG9zIGFlcm9wdWVydG9zIGRlbCBQZXLDug0KDQotICAgQ29tcGFyYXIgbG9zIGluZ3Jlc29zIHRvdGFsZXMgY29uIGVsIG7Dum1lcm8gZGUgcGFzYWplcm9zIGVuIGxvcyBhZXJvcHVlcnRvcyBkZWwgUGVyw7ogZXZhbHVhbmRvIHN1IGluZmx1ZW5jaWENCg0KLSAgIERldGVybWluYXIgZWwgYWVyb3B1ZXJ0byBjb24gbWF5b3IgYWZsdWVuY2lhIGRlIHBhc2FqZXJvcyB5IGVsIGRlIG1heW9yIGluZ3Jlc29zIGRlbCBQZXLDug0KDQotICAgQ29tcGFyYXIgbG9zIGluZ3Jlc29zIHRvdGFsZXMgKFVTJCkgZHVyYW50ZSBsYSBwYW5kZW1pYSB5IHBvc3QgcGFuZGVtaWEgZW4gZWwgUGVyw7oNCg0KIyMgVGFibGEgZGUgdmFyaWFibGVzDQoNCiMgTGlicmVyw61hcw0KDQpgYGB7ciBlY2hvPUZBTFNFfQ0Kcm0obGlzdD1scygpKQ0KbGlicmFyeShwbHlyKQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KHRpZHlyKQ0KDQpgYGANCg0KIyBCYXNlIGRlIGRhdG9zDQoNCmBgYHtyIGVjaG89RkFMU0V9DQpJVFMgPC0gcmVhZF9jc3YoIlJlY2F1ZGFjaW9uSW5ncmVzb3NUb3RhbGVzLmNzdiIpDQpJUlM8LSByZWFkX2NzdigiUmVjYXVkYWNpb25JbmdyZXNvc1JlZ3VsYWRvcy5jc3YiKQ0KVFAgPC0gcmVhZF9jc3YoIlRyYWZpY29QYXNhamVyb3MuY3N2IikNCmBgYA0KIyAqKkRhdG9zKioNCg0KIyMgVGFibGEgZGUgdmFyaWFibGVzDQoNCkHDsW86IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSBpbmRpY2EgZWwgYcOxbyBkZSBsYSByZWNvbGVjY2nDs24gZGUgaW5mb3JtYWNpw7NuLg0KDQpNZXM6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSBpbmRpY2EgZWwgbWVzIGRlIGxhIHJlY29sZWNjacOzbiBkZSBpbmZvcm1hY2nDs24uDQoNCkFlcm9wdWVydG86IFZhcmlhYmxlIGN1YWxpdGF0aXZhIHF1ZSBpbmRpY2EgZWwgYWVyb3B1ZXJ0byBkZWwgY3VhbCBzZSByZWNvbGVjdGEgbGEgaW5mb3JtYWNpw7NuDQoNCkluZnJhZXN0cnVjdHVyYTogVmFyaWFibGUgY3VhbGl0YXRpdmEgcXVlIGluZGljYSBhIHF1ZSBlbnRpZGFkIHBlcnRlbmVjZSBsYSBpbmZyYWVzdHJ1Y3R1cmEgZGVsIGFlcm9wdWVydG8gZGVsIGN1YWwgc2UgcmVjb2xlY3RhIGxhIGluZm9ybWFjacOzbi4NCg0KSVQ6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBsb3MgaW5ncmVzb3MgdG90YWxlcyBlbiBkb2xhcmVzIHF1ZSBoYSByZWdpc3RyYWRvIGVsIGFlcm9wdWVydG8NCg0KSVI6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBsb3MgaW5ncmVzb3MgcmVndWxhZG9zIGVuIGRvbGFyZXMgcXVlIGhhIHJlZ2lzdHJhZG8gZWwgYWVyb3B1ZXJ0bw0KDQpUVVVBTjogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBxdWUgaGEgZ2VuZXJhZG8gbGEgVEFSSUZBIFVOSUZJQ0FEQSBQT1IgVVNPIERFIEFFUk9QVUVSVE8gZGUgdGlwbyBuYWNpb25hbC4NCg0KVFVVQU46IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgcXVlIGhhIGdlbmVyYWRvIGxhIFRBUklGQSBVTklGSUNBREEgUE9SIFVTTyBERSBBRVJPUFVFUlRPIGRlIHRpcG8gaW50ZXJuYWNpb25hbC4NCg0KTlBJOiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgbnVtZXJvIGRlIHBhc2FqZXJvcyBpbnRlcm5hY2lvbmFsZXMgcXVlIGhhIHJlZ2lzdHJhZG8gZWwgYWVyb3B1ZXJ0bw0KDQpOUE46IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBudW1lcm8gZGUgcGFzYWplcm9zIG5hY2lvbmFsZXMgcXVlIGhhIHJlZ2lzdHJhZG8gZWwgYWVyb3B1ZXJ0bw0KDQpJUkFEX1ZFUjogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBhdGVycml6YWplIHkgZGVzcGVndWUuDQoNCklSQUQ6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgZGVsIGFlcm9wdWVydG8gcG9yIGF0ZXJyaXphamUgeSBkZXNwZWd1ZS4NCg0KQUFETV9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgZWwgYWxxdWlsZXIgZGUgw6FyZWFzIGRlIG1hbnRlbmltaWVudG8uDQoNCkFBRE06IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgcG9yIGVsIGFscXVpbGVyIGRlIMOhcmVhcyBkZSBtYW50ZW5pbWllbnRvLg0KDQpBREVQX1ZFUjogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBlbCBhbHF1aWxlciBkZSBlc3BhY2lvcyBkZSBwdWJsaWNpZGFkLg0KDQpBREVQOiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciBlbCBhbHF1aWxlciBkZSBlc3BhY2lvcyBkZSBwdWJsaWNpZGFkLg0KDQpBTENfVkVSOiBWYXJpYWJsZSBjYXRlZ8OzcmljYSBxdWUgcmVwcmVzZW50YSBzaSBlbCBhZXJvcHVlcnRvIG9idGllbmUgaW5ncmVzb3MgcG9yIGVsIGFscXVpbGVyIGRlIGxvY2FsZXMgY29tZXJjaWFsZXMuDQoNCkFMQzogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgYWxxdWlsZXIgZGUgbG9jYWxlcyBjb21lcmNpYWxlcy4NCg0KQU9PQV9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgZWwgYWxxdWlsZXIgZGUgb2ZpY2luYXMgZGUgb3BlcmFjaW9uZXMgZGUgYWVyb2zDrW5lYXMuDQoNCkFPT0E6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgcG9yIGVsIGFscXVpbGVyIGRlIG9maWNpbmFzIGRlIG9wZXJhY2lvbmVzIGRlIGFlcm9sw61uZWFzLg0KDQpBREFIX1ZFUjogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBlbCBhbHF1aWxlciBkZSBhbG1hY2VuZXMvaGFuZ2FyZXMuDQoNCkFEQUg6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgcG9yIGVsIGFscXVpbGVyIGRlIGFsbWFjZW5lcy9oYW5nYXJlcy4NCg0KQUVIRV9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgbGEgYXRlbmNpw7NuIGVuIGhvcmFzIGV4dHJhcy4NCg0KQUVIRTogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgbGEgYXRlbmNpw7NuIGVuIGhvcmFzIGV4dHJhcy4NCg0KSVJFQV9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgZWwgZXN0YWNpb25hbWllbnRvIGRlIGFlcm9uYXZlcy4NCg0KSVJFQTogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgZXN0YWNpb25hbWllbnRvIGRlIGFlcm9uYXZlcy4NCg0KSVJJRl9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgcmVlbWJvbHNvIGVuIGluZ3Jlc29zIGZpbmFuY2llcm9zLg0KDQpJUklGOiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciByZWVtYm9sc28gZW4gaW5ncmVzb3MgZmluYW5jaWVyb3MuDQoNCklSUl9WRVI6IFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgcmVlbWJvbHNvcy4NCg0KSVJSOiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciByZWVtYm9sc29zLg0KDQpOUDogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIG51bWVybyBkZSBwYXNhamVyb3MgdG90YWxlcyBxdWUgaGEgcmVnaXN0cmFkbyBlbCBhZXJvcHVlcnRvLg0KDQoNCiMgQ3JlYWNpw7NuIGRlbCBEYXRhZnJhbWUNCg0KQ3JlYW5kbyBlbCBEYXRhRnJhbWUgYSBwYXJ0aXIgZGUgbGEgdmFyaWFibGUgSW5ncmVzb3MgVG90YWxlcyAoSVQpDQoNCmBgYHtyfQ0KSVRTIDwtIGZpbHRlcihJVFMsIEHDsW8gJWluJSBjKCIyMDIwIiwiMjAyMSIsIjIwMjIiKSkNCklUUyAlPiUgZ3JvdXBfYnkoQcOxbyxNZXMsQWVyb3B1ZXJ0byxJbmZyYWVzdHJ1Y3R1cmEpICU+JSBzdW1tYXJpc2UoSVQgPSBzdW0oYEltcG9ydGUgcG9yIFNlcnZpY2lvc2ApKSAtPiBERg0KYGBgDQoNCkltcG9ydGFudGU6IFNlIHRvbWEgZW4gY3VlbnRhIHF1ZSBhbCB1biBhZXJvcHVlcnRvIG5vIGRlY2xhcmFyIHVuIGltcG9ydGUgZGUgc2VydmljaW9zIHBvciB1biB0aXBvIGRlIHJ1YnJvIGNvbW8gZWwgKiphbHF1aWxlciBkZSBlc3BhY2lvcyBwdWJsaWNpdGFyaW9zKiosIGxvcyBpbmdyZXNvcyBlbiBlc3RlIHJ1YnJvIHNlcsOhbiAwLiBQYXJhIGVzdG8gY3JlYXJlbW9zIHVuYSB2YXJpYWJsZSBjb25qdW50YSBhbCBydWJybyBkZSBpbXBvcnRlIHF1ZSB2ZXJpZmljYXLDoSBzaSBlc3RlIGhhIHNpZG8gZGVjbGFyYWRvIG8gbm8sIHNlIGlkZW50aWZpY2Fyw6EgY29uIGVsIG5vbWJyZSBkZSBsYSB2YXJpYWJsZSB5IHVuIHN1ZmlqbyAiXF9WRVIiLiBQZXNlIGEgcXVlIGVzdGEgb3BlcmFjacOzbiBnZW5lcmEgc2VzZ28sIGFsIHRlbmVyIHVuIHNlbnRpZG8gY29uIGxhIHJlYWxpZGFkIHNlIGNvbnNpZGVyYSBxdWUgbm8gZXMgc2lnbmlmaWNhdGl2by4NCg0KVW5pZW5kbyBsYSB2YXJpYWJsZSBOdW1lcm8gZGUgUGFzYWplcm9zIEludGVybmFjaW9uYWxlcyAoTlBJKQ0KDQpgYGB7cn0NClBJIDwtIGZpbHRlcihUUCwgYFRpcG8gZGUgUGFzYWplcm9gID09ICJJTlRFUk5BQ0lPTkFMIikNClBJIDwtIGZpbHRlcihQSSxBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpQSSA8LSBzZWxlY3QoUEksIC1QZXJpb2RvKQ0KUEkgPC0gc2VsZWN0KFBJLCAtYFRpcG8gZGUgUGFzYWplcm9gKQ0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsUEksIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsID0gVFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIk5QSSIgPSAiTnJvIFBhc2FqZXJvcyIpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFfQ0KREYkTlBJW2lzLm5hKERGJE5QSSldIDwtIDANCg0KI1JlZW1wbGF6byBkZSBOL0EncyBwb3IgMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgTnVtZXJvIGRlIFBhc2FqZXJvcyBOYWNpb25hbGVzIChOUE4pDQoNCmBgYHtyfQ0KUE4gPC0gZmlsdGVyKFRQLCBgVGlwbyBkZSBQYXNhamVyb2AgPT0gIk5BQ0lPTkFMIikNClBOIDwtIGZpbHRlcihQTixBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpQTiA8LSBzZWxlY3QoUE4sIC1QZXJpb2RvKQ0KUE4gPC0gc2VsZWN0KFBOLCAtYFRpcG8gZGUgUGFzYWplcm9gKQ0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsUE4sIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJOUE4iID0gIk5ybyBQYXNhamVyb3MiKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRX0NCkRGJE5QTltpcy5uYShERiROUE4pXSA8LSAwDQoNCiNSZWVtcGxhem8gZGUgTi9BJ3MgcG9yIDANCmBgYA0KDQpVbmllbmRvIGxhIHZhcmlhYmxlIEluZ3Jlc28gUnVicm8gVCBVIFUgQSBOQUNJT05BTCAoVFVVQU4pDQoNCmBgYHtyfQ0KVFVVQU4gPC0gZmlsdGVyKElUUywgYFJ1YnJvIEluZ3Jlc29gID09ICJUIFUgVSBBIE5BQ0lPTkFMIikNClRVVUFOIDwtIGZpbHRlcihUVVVBTixBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpUVVVBTiA8LSBzZWxlY3QoVFVVQU4sIC0nVGlwbyBJbmdyZXNvJykNClRVVUFOIDwtIHNlbGVjdChUVVVBTiwgLSdSdWJybyBJbmdyZXNvJykNClRVVUFOIDwtIHNlbGVjdChUVVVBTiwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCiNDcmVhY2nDs24gZGUgdmFyaWFibGUgZGUgdmVyaWZpY2FjacOzbiBwYXJhIHJlZW1wbGF6byBkZSBOL0Encw0KREYgPC0gbWVyZ2UoREYsIFRVVUFOLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiVFVVQU5fVkVSIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsIFRVVUFOLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiVFVVQU4iID0gIkltcG9ydGUgcG9yIFNlcnZpY2lvcyIpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFfQ0KREYkVFVVQU5fVkVSW2lzLm5hKERGJFRVVUFOX1ZFUildIDwtIDANCkRGJFRVVUFOX1ZFUltERiRUVVVBTl9WRVIgIT0gMF0gPC0gIlNpIg0KREYkVFVVQU5fVkVSW0RGJFRVVUFOX1ZFUiA9PSAiMCJdIDwtICJObyINCkRGJFRVVUFOW2lzLm5hKERGJFRVVUFOKV0gPC0gMA0KI1JlZW1wbGF6byBkZSBOL0EncyBwb3IgMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBUIFUgVSBBIElOVEVSTkFDSU9OQUwgKFRVVUFJKQ0KDQpgYGB7cn0NClRVVUFJIDwtIGZpbHRlcihJVFMsIGBSdWJybyBJbmdyZXNvYCA9PSAiVCBVIFUgQSBJTlRFUk5BQ0lPTkFMIikNClRVVUFJIDwtIGZpbHRlcihUVVVBSSxBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpUVVVBSSA8LSBzZWxlY3QoVFVVQUksIC0nVGlwbyBJbmdyZXNvJykNClRVVUFJIDwtIHNlbGVjdChUVVVBSSwgLSdSdWJybyBJbmdyZXNvJykNClRVVUFJIDwtIHNlbGVjdChUVVVBSSwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBUVVVBSSwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIlRVVUFJX1ZFUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikjQ3JlYWNpw7NuIGRlIHZhcmlhYmxlIGRlIHZlcmlmaWNhY2nDs24gcGFyYSByZWVtcGxhem8gZGUgTi9BJ3MNCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBUVVVBSSwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIlRVVUFJIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRX0NCg0KREYkVFVVQUlfVkVSW2lzLm5hKERGJFRVVUFJX1ZFUildIDwtIDANCkRGJFRVVUFJX1ZFUltERiRUVVVBSV9WRVIgIT0gMF0gPC0gIlNpIg0KREYkVFVVQUlfVkVSW0RGJFRVVUFJX1ZFUiA9PSAiMCJdIDwtICJObyINCkRGJFRVVUFJW2lzLm5hKERGJFRVVUFJKV0gPC0gMA0KI1JlZW1wbGF6byBkZSBOL0EncyBwb3IgMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBBVEVSUklaQUpFIFkgREVTUEVHVUUgKElSQUQpDQoNCmBgYHtyfQ0KSVJBRCA8LSBmaWx0ZXIoSVRTLCBgUnVicm8gSW5ncmVzb2AgPT0gIkFURVJSSVpBSkUgWSBERVNQRUdVRSIpDQpJUkFEIDwtIGZpbHRlcihJUkFELEHDsW8gJWluJSBjKDIwMjAsMjAyMSwyMDIyKSkNCklSQUQgPC0gc2VsZWN0KElSQUQsIC0nVGlwbyBJbmdyZXNvJykNCklSQUQgPC0gc2VsZWN0KElSQUQsIC0nUnVicm8gSW5ncmVzbycpDQpJUkFEIDwtIHNlbGVjdChJUkFELCAtJ1BlcmlvZG8nKQ0KYGBgDQoNCmBgYHtyfQ0KDQpERiA8LSBtZXJnZShERiwgSVJBRCwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIklSQURfVkVSIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KI0NyZWFjacOzbiBkZSB2YXJpYWJsZSBkZSB2ZXJpZmljYWNpw7NuIHBhcmEgcmVlbXBsYXpvIGRlIE4vQSdzDQpgYGANCg0KYGBge3J9DQpERiA8LSBtZXJnZShERiwgSVJBRCwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIklSQUQiID0gIkltcG9ydGUgcG9yIFNlcnZpY2lvcyIpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFfQ0KDQpERiRJUkFEX1ZFUltpcy5uYShERiRJUkFEX1ZFUildIDwtIDANCkRGJElSQURfVkVSW0RGJElSQURfVkVSICE9IDBdIDwtICJTaSINCkRGJElSQURfVkVSW0RGJElSQURfVkVSID09ICIwIl0gPC0gIk5vIg0KREYkSVJBRFtpcy5uYShERiRJUkFEKV0gPC0gMA0KI1JlZW1wbGF6byBkZSBOL0EncyBwb3IgMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBBTFFVSUxFUiBBUkVBUyBERSBNQU5URU5JTUlFTlRPIChBQURNKQ0KDQpgYGB7cn0NCkFBRE0gPC0gZmlsdGVyKElUUywgYFJ1YnJvIEluZ3Jlc29gID09ICJBTFFVSUxFUiBBUkVBUyBERSBNQU5URU5JTUlFTlRPIikNCkFBRE0gPC0gZmlsdGVyKEFBRE0sQcOxbyAlaW4lIGMoMjAyMCwyMDIxLDIwMjIpKQ0KQUFETSA8LSBzZWxlY3QoQUFETSwgLSdUaXBvIEluZ3Jlc28nKQ0KQUFETSA8LSBzZWxlY3QoQUFETSwgLSdSdWJybyBJbmdyZXNvJykNCkFBRE0gPC0gc2VsZWN0KEFBRE0sIC0nUGVyaW9kbycpDQpgYGANCg0KYGBge3J9DQoNCkRGIDwtIG1lcmdlKERGLCBBQURNLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiQUFETV9WRVIiID0gIkltcG9ydGUgcG9yIFNlcnZpY2lvcyIpDQojQ3JlYWNpw7NuIGRlIHZhcmlhYmxlIGRlIHZlcmlmaWNhY2nDs24gcGFyYSByZWVtcGxhem8gZGUgTi9BJ3MNCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBBQURNLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiQUFETSIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQoNCkRGJEFBRE1fVkVSW2lzLm5hKERGJEFBRE1fVkVSKV0gPC0gMA0KREYkQUFETV9WRVJbREYkQUFETV9WRVIgIT0gMF0gPC0gIlNpIg0KREYkQUFETV9WRVJbREYkQUFETV9WRVIgPT0gIjAiXSA8LSAiTm8iDQpERiRBQURNW2lzLm5hKERGJEFBRE0pXSA8LSAwDQojUmVlbXBsYXpvIGRlIE4vQSdzIHBvciAwDQpgYGANCg0KVW5pZW5kbyBsYSB2YXJpYWJsZSBJbmdyZXNvIEFMUVVJTEVSIERFIEVTUEFDSU9TIFBVQkxJQ0lUQVJJT1MgKEFERVApDQoNCmBgYHtyfQ0KQURFUCA8LSBmaWx0ZXIoSVRTLCBgUnVicm8gSW5ncmVzb2AgPT0gIkFMUVVJTEVSIERFIEVTUEFDSU9TIFBVQkxJQ0lUQVJJT1MiKQ0KQURFUCA8LSBmaWx0ZXIoQURFUCxBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpBREVQIDwtIHNlbGVjdChBREVQLCAtJ1RpcG8gSW5ncmVzbycpDQpBREVQIDwtIHNlbGVjdChBREVQLCAtJ1J1YnJvIEluZ3Jlc28nKQ0KQURFUCA8LSBzZWxlY3QoQURFUCwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCg0KREYgPC0gbWVyZ2UoREYsIEFERVAsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJBREVQX1ZFUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCiNDcmVhY2nDs24gZGUgdmFyaWFibGUgZGUgdmVyaWZpY2FjacOzbiBwYXJhIHJlZW1wbGF6byBkZSBOL0Encw0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsIEFERVAsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJBREVQIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRX0NCg0KREYkQURFUF9WRVJbaXMubmEoREYkQURFUF9WRVIpXSA8LSAwDQpERiRBREVQX1ZFUltERiRBREVQX1ZFUiAhPSAwXSA8LSAiU2kiDQpERiRBREVQX1ZFUltERiRBREVQX1ZFUiA9PSAiMCJdIDwtICJObyINCkRGJEFERVBbaXMubmEoREYkQURFUCldIDwtIDANCiNSZWVtcGxhem8gZGUgTi9BJ3MgcG9yIDANCmBgYA0KDQpVbmllbmRvIGxhIHZhcmlhYmxlIEluZ3Jlc28gQUxRVUlMRVIgTE9DQUxFUyBDT01FUkNJQUxFUyAoQUxDKQ0KDQpgYGB7cn0NCkFMQyA8LSBmaWx0ZXIoSVRTLCBgUnVicm8gSW5ncmVzb2AgPT0gIkFMUVVJTEVSIExPQ0FMRVMgQ09NRVJDSUFMRVMiKQ0KQUxDIDwtIGZpbHRlcihBTEMsQcOxbyAlaW4lIGMoMjAyMCwyMDIxLDIwMjIpKQ0KQUxDIDwtIHNlbGVjdChBTEMsIC0nVGlwbyBJbmdyZXNvJykNCkFMQyA8LSBzZWxlY3QoQUxDLCAtJ1J1YnJvIEluZ3Jlc28nKQ0KQUxDIDwtIHNlbGVjdChBTEMsIC0nUGVyaW9kbycpDQpgYGANCg0KYGBge3J9DQoNCkRGIDwtIG1lcmdlKERGLCBBTEMsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJBTENfVkVSIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KI0NyZWFjacOzbiBkZSB2YXJpYWJsZSBkZSB2ZXJpZmljYWNpw7NuIHBhcmEgcmVlbXBsYXpvIGRlIE4vQSdzIA0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsIEFMQywgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIkFMQyIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQoNCkRGJEFMQ19WRVJbaXMubmEoREYkQUxDX1ZFUildIDwtIDANCkRGJEFMQ19WRVJbREYkQUxDX1ZFUiAhPSAwXSA8LSAiU2kiDQpERiRBTENfVkVSW0RGJEFMQ19WRVIgPT0gIjAiXSA8LSAiTm8iDQpERiRBTENbaXMubmEoREYkQUxDKV0gPC0gMA0KI1JlZW1wbGF6byBkZSBOL0EncyBwb3IgMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBBTFFVSUxFUiBPRklDSU5BUyBPUEVSQUNJT05FUyBBRVJPTMONTkVBUyAoQU9PQSkNCg0KYGBge3J9DQpBT09BIDwtIGZpbHRlcihJVFMsIGBSdWJybyBJbmdyZXNvYCA9PSAiQUxRVUlMRVIgT0ZJQ0lOQVMgT1BFUkFDSU9ORVMgQUVST0zDjU5FQVMiKQ0KQU9PQSA8LSBmaWx0ZXIoQU9PQSxBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpBT09BIDwtIHNlbGVjdChBT09BLCAtJ1RpcG8gSW5ncmVzbycpDQpBT09BIDwtIHNlbGVjdChBT09BLCAtJ1J1YnJvIEluZ3Jlc28nKQ0KQU9PQSA8LSBzZWxlY3QoQU9PQSwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCg0KREYgPC0gbWVyZ2UoREYsIEFPT0EsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJBT09BX1ZFUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCiNDcmVhY2nDs24gZGUgdmFyaWFibGUgZGUgdmVyaWZpY2FjacOzbiBwYXJhIHJlZW1wbGF6byBkZSBOL0EncyANCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBBT09BLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiQU9PQSIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQpERiRBT09BX1ZFUltpcy5uYShERiRBT09BX1ZFUildIDwtIDANCkRGJEFPT0FfVkVSW0RGJEFPT0FfVkVSICE9IDBdIDwtICJTaSINCkRGJEFPT0FfVkVSW0RGJEFPT0FfVkVSID09ICIwIl0gPC0gIk5vIg0KREYkQU9PQVtpcy5uYShERiRBT09BKV0gPC0gMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBBTFFVSUxFUkVTIERFIEFMTUFDRU4vSEFOR0FSIChBREFIKQ0KDQpgYGB7cn0NCkFEQUggPC0gZmlsdGVyKElUUywgYFJ1YnJvIEluZ3Jlc29gID09ICJBTFFVSUxFUkVTIERFIEFMTUFDRU4vSEFOR0FSIikNCkFEQUggPC0gZmlsdGVyKEFEQUgsQcOxbyAlaW4lIGMoMjAyMCwyMDIxLDIwMjIpKQ0KQURBSCA8LSBzZWxlY3QoQURBSCwgLSdUaXBvIEluZ3Jlc28nKQ0KQURBSCA8LSBzZWxlY3QoQURBSCwgLSdSdWJybyBJbmdyZXNvJykNCkFEQUggPC0gc2VsZWN0KEFEQUgsIC0nUGVyaW9kbycpDQpgYGANCg0KYGBge3J9DQoNCkRGIDwtIG1lcmdlKERGLCBBREFILCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiQURBSF9WRVIiID0gIkltcG9ydGUgcG9yIFNlcnZpY2lvcyIpDQojQ3JlYWNpw7NuIGRlIHZhcmlhYmxlIGRlIHZlcmlmaWNhY2nDs24gcGFyYSByZWVtcGxhem8gZGUgTi9BJ3MgDQpgYGANCg0KYGBge3J9DQpERiA8LSBtZXJnZShERiwgQURBSCwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIkFEQUgiID0gIkltcG9ydGUgcG9yIFNlcnZpY2lvcyIpDQpgYGANCg0KYGBge3IgZXZhbD1UUlVFfQ0KREYkQURBSF9WRVJbaXMubmEoREYkQURBSF9WRVIpXSA8LSAwDQpERiRBREFIX1ZFUltERiRBREFIX1ZFUiAhPSAwXSA8LSAiU2kiDQpERiRBREFIX1ZFUltERiRBREFIX1ZFUiA9PSAiMCJdIDwtICJObyINCkRGJEFEQUhbaXMubmEoREYkQURBSCldIDwtIDANCmBgYA0KDQpVbmllbmRvIGxhIHZhcmlhYmxlIEluZ3Jlc28gUnVicm8gQVRFTkNJw5NOIEVOIEhPUkFTIEVYVFJBUyAoQUVIRSkNCg0KYGBge3J9DQpBRUhFIDwtIGZpbHRlcihJVFMsIGBSdWJybyBJbmdyZXNvYCA9PSAiQVRFTkNJw5NOIEVOIEhPUkFTIEVYVFJBUyIpDQpBRUhFIDwtIGZpbHRlcihBRUhFLEHDsW8gJWluJSBjKDIwMjAsMjAyMSwyMDIyKSkNCkFFSEUgPC0gc2VsZWN0KEFFSEUsIC0nVGlwbyBJbmdyZXNvJykNCkFFSEUgPC0gc2VsZWN0KEFFSEUsIC0nUnVicm8gSW5ncmVzbycpDQpBRUhFIDwtIHNlbGVjdChBRUhFLCAtJ1BlcmlvZG8nKQ0KYGBgDQoNCmBgYHtyfQ0KDQpERiA8LSBtZXJnZShERiwgQUVIRSwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIkFFSEVfVkVSIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KI0NyZWFjacOzbiBkZSB2YXJpYWJsZSBkZSB2ZXJpZmljYWNpw7NuIHBhcmEgcmVlbXBsYXpvIGRlIE4vQSdzIA0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsIEFFSEUsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJBRUhFIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KYGBgDQoNCmBgYHtyIGV2YWw9VFJVRX0NCkRGJEFFSEVfVkVSW2lzLm5hKERGJEFFSEVfVkVSKV0gPC0gMA0KREYkQUVIRV9WRVJbREYkQUVIRV9WRVIgIT0gMF0gPC0gIlNpIg0KREYkQUVIRV9WRVJbREYkQUVIRV9WRVIgPT0gIjAiXSA8LSAiTm8iDQpERiRBRUhFW2lzLm5hKERGJEFFSEUpXSA8LSAwDQpgYGANCg0KVW5pZW5kbyBsYSB2YXJpYWJsZSBJbmdyZXNvIFJ1YnJvIEVTVEFDSU9OQU1JRU5UTyBBRVJPTkFWRVMgKElSRUEpDQoNCmBgYHtyfQ0KSVJFQSA8LSBmaWx0ZXIoSVRTLCBgUnVicm8gSW5ncmVzb2AgPT0gIkVTVEFDSU9OQU1JRU5UTyBBRVJPTkFWRVMiKQ0KSVJFQSA8LSBmaWx0ZXIoSVJFQSxBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpJUkVBIDwtIHNlbGVjdChJUkVBLCAtJ1RpcG8gSW5ncmVzbycpDQpJUkVBIDwtIHNlbGVjdChJUkVBLCAtJ1J1YnJvIEluZ3Jlc28nKQ0KSVJFQSA8LSBzZWxlY3QoSVJFQSwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCg0KREYgPC0gbWVyZ2UoREYsIElSRUEsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJJUkVBX1ZFUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCiNDcmVhY2nDs24gZGUgdmFyaWFibGUgZGUgdmVyaWZpY2FjacOzbiBwYXJhIHJlZW1wbGF6byBkZSBOL0EncyANCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBJUkVBLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiSVJFQSIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQpERiRJUkVBX1ZFUltpcy5uYShERiRJUkVBX1ZFUildIDwtIDANCkRGJElSRUFfVkVSW0RGJElSRUFfVkVSICE9IDBdIDwtICJTaSINCkRGJElSRUFfVkVSW0RGJElSRUFfVkVSID09ICIwIl0gPC0gIk5vIg0KREYkSVJFQVtpcy5uYShERiRJUkVBKV0gPC0gMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBJTkdSRVNPUyBGSU5BTkNJRVJPUyAoSVJJRikNCg0KYGBge3J9DQpJUklGIDwtIGZpbHRlcihJVFMsIGBSdWJybyBJbmdyZXNvYCA9PSAiSU5HUkVTT1MgRklOQU5DSUVST1MiKQ0KSVJJRiA8LSBmaWx0ZXIoSVJJRixBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpJUklGIDwtIHNlbGVjdChJUklGLCAtJ1RpcG8gSW5ncmVzbycpDQpJUklGIDwtIHNlbGVjdChJUklGLCAtJ1J1YnJvIEluZ3Jlc28nKQ0KSVJJRiA8LSBzZWxlY3QoSVJJRiwgLSdQZXJpb2RvJykNCmBgYA0KDQpgYGB7cn0NCg0KREYgPC0gbWVyZ2UoREYsIElSSUYsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJJUklGX1ZFUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCiNDcmVhY2nDs24gZGUgdmFyaWFibGUgZGUgdmVyaWZpY2FjacOzbiBwYXJhIHJlZW1wbGF6byBkZSBOL0EncyANCmBgYA0KDQpgYGB7cn0NCkRGIDwtIG1lcmdlKERGLCBJUklGLCBieSA9IGMoIkHDsW8iLCJNZXMiLCJBZXJvcHVlcnRvIiwiSW5mcmFlc3RydWN0dXJhIiksIGFsbD1UUlVFKQ0KREYgPC0gcmVuYW1lKERGLCAiSVJJRiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQpERiRJUklGX1ZFUltpcy5uYShERiRJUklGX1ZFUildIDwtIDANCkRGJElSSUZfVkVSW0RGJElSSUZfVkVSICE9IDBdIDwtICJTaSINCkRGJElSSUZfVkVSW0RGJElSSUZfVkVSID09ICIwIl0gPC0gIk5vIg0KREYkSVJJRltpcy5uYShERiRJUklGKV0gPC0gMA0KYGBgDQoNClVuaWVuZG8gbGEgdmFyaWFibGUgSW5ncmVzbyBSdWJybyBSRUVNQk9MU09TIChJUlIpDQoNCmBgYHtyfQ0KSVJSIDwtIGZpbHRlcihJVFMsIGBSdWJybyBJbmdyZXNvYCA9PSAiUkVFTUJPTFNPUyIpDQpJUlIgPC0gZmlsdGVyKElSUixBw7FvICVpbiUgYygyMDIwLDIwMjEsMjAyMikpDQpJUlIgPC0gc2VsZWN0KElSUiwgLSdUaXBvIEluZ3Jlc28nKQ0KSVJSIDwtIHNlbGVjdChJUlIsIC0nUnVicm8gSW5ncmVzbycpDQpJUlIgPC0gc2VsZWN0KElSUiwgLSdQZXJpb2RvJykNCg0KSVJSIDwtIGZpbHRlcihJUlIsIGBJbXBvcnRlIHBvciBTZXJ2aWNpb3NgICE9IDApDQpgYGANCg0KYGBge3J9DQoNCkRGIDwtIG1lcmdlKERGLCBJUlIsIGJ5ID0gYygiQcOxbyIsIk1lcyIsIkFlcm9wdWVydG8iLCJJbmZyYWVzdHJ1Y3R1cmEiKSwgYWxsPVRSVUUpDQpERiA8LSByZW5hbWUoREYsICJJUlJfVkVSIiA9ICJJbXBvcnRlIHBvciBTZXJ2aWNpb3MiKQ0KI0NyZWFjacOzbiBkZSB2YXJpYWJsZSBkZSB2ZXJpZmljYWNpw7NuIHBhcmEgcmVlbXBsYXpvIGRlIE4vQSdzIA0KYGBgDQoNCmBgYHtyfQ0KREYgPC0gbWVyZ2UoREYsIElSUiwgYnkgPSBjKCJBw7FvIiwiTWVzIiwiQWVyb3B1ZXJ0byIsIkluZnJhZXN0cnVjdHVyYSIpLCBhbGw9VFJVRSkNCkRGIDwtIHJlbmFtZShERiwgIklSUiIgPSAiSW1wb3J0ZSBwb3IgU2VydmljaW9zIikNCmBgYA0KDQpgYGB7ciBldmFsPVRSVUV9DQpERiRJUlJfVkVSW2lzLm5hKERGJElSUl9WRVIpXSA8LSAwDQpERiRJUlJfVkVSW0RGJElSUl9WRVIgIT0gMF0gPC0gIlNpIg0KREYkSVJSX1ZFUltERiRJUlJfVkVSID09ICIwIl0gPC0gIk5vIg0KREYkSVJSW2lzLm5hKERGJElSUildIDwtIDANCmBgYA0KDQpDcmVhbmRvIGxhIHZhcmlhYmxlIE51bWVybyBkZSBQYXNhamVyb3MgdG90YWxlcyAoTlApDQoNCmBgYHtyfQ0KREYgJT4lIG11dGF0ZShOUCA9IE5QTiArIE5QSSkgLT4gREYNCiNOdW1lcm8gZGUgcGFzYWplcm9zIHRvdGFsZXMNCmBgYA0KDQpPcmdhbml6YW5kbyBlbCBERg0KDQpgYGB7cn0NCkRGJE1lcyA9IGZhY3RvcihERiRNZXMsIGxldmVscyA9YygiRW5lcm8iLCJGZWJyZXJvIiwiTWFyem8iLCJBYnJpbCIsIk1heW8iLCJKdW5pbyIsIkp1bGlvIiwiQWdvc3RvIiwiU2V0aWVtYnJlIiwiT2N0dWJyZSIsIk5vdmllbWJyZSIsIkRpY2llbWJyZSIpKQ0KREYgPC0gYXJyYW5nZShERiwgQcOxbywgTWVzKQ0KYGBgDQoNCiMjIExpbXBpZXphIGRlIGRhdG9zDQoNClNlIGNvbnNpZGVyYSBxdWUgZW4gY2FzbyBubyBzZSBjdWVudGUgY29uIGVsIG5vbWJyZSBkZWwgYWVyb3B1ZXJ0byBvIHN1IGluZnJhZXN0cnVjdHVyYSAoU2llbXByZSBkZWJlIHZlbmlyIGFjb21wYcOxYWRhIGRlbCBub21icmUpLCBsYSB1bmlkYWQgbXVlc3RyYWwgbm8gcG9kcsOhIGVudHJhciBhbCBhbsOhbGlzaXMgcHVlcyBwb3IgZWplbXBsbyBzaSBub3MgZGljZW4gY3VhbnRvIGdhbm8gdW4gYWVyb3B1ZXJ0byBkZXNjb25vY2lkbywgZXN0byBubyBub3MgZGlyw6EgbmFkYSB5IHBvciBlbGxvIGxhIGVsaW1pbmFyZW1vcy4NCg0KYGBge3J9DQoNCkRGJEFlcm9wdWVydG9bREYkQWVyb3B1ZXJ0byA9PSAnTm8gcHJlY2lzYSddIDwtIE5BDQpERiRBZXJvcHVlcnRvW0RGJEFlcm9wdWVydG8gPT0gJy0nXSA8LSBOQQ0KREYkSW5mcmFlc3RydWN0dXJhW0RGJEluZnJhZXN0cnVjdHVyYSA9PSAnLSddIDwtIE5BDQoNCkRGIDwtIGZpbHRlcihERiwgSW5mcmFlc3RydWN0dXJhICE9IGlzLm5hKCJJbmZyYWVzdHJ1Y3R1cmEiKSAmIEFlcm9wdWVydG8gIT0gaXMubmEoIkFlcm9wdWVydG8iKSkNCmBgYA0KDQpDYW1iaWFtb3MgbG9zIG5vbWJyZXMgZGUgbGEgdmFyaWFibGUgSW5mcmFlc3RydWN0dXJhOg0KDQpgYGB7cn0NCg0KREYgJT4lIG11dGF0ZSgiSW5mcmFlc3RydWN0dXJhIiA9DQogICAgICAgICAgICAgICAgICBpZmVsc2UoSW5mcmFlc3RydWN0dXJhPT0iQURQIiwgIkFlcm9wdWVydG9zIGRlbCBQZXLDuiBTLkEuIiwNCiAgICAgICAgICAgICAgICAgIGlmZWxzZShJbmZyYWVzdHJ1Y3R1cmE9PSJBQVAiLCAiQWVyb3B1ZXJ0b3MgQW5kaW5vcyBkZWwgUGVyw7ogUy5BLiIsDQogICAgICAgICAgICAgICAgICBpZmVsc2UoSW5mcmFlc3RydWN0dXJhPT0iQ09SIiwgIkNPUlBBQyBTLkEuIiwNCiAgICAgICAgICAgICAgICAgIGlmZWxzZShJbmZyYWVzdHJ1Y3R1cmE9PSJMQVAiLCAiTGltYSBBaXJwb3J0IFBhcnRuZXJzIFMuUi5MLiIsSW5mcmFlc3RydWN0dXJhKSkpKSkgLT4gREYNCmBgYA0KDQpFbGltaW5hbW9zIGxhcyB2YXJpYWJsZXMgdGVtcG9yYWxlczoNCg0KYGBge3J9DQpybShsaXN0ID0gYygiQUFETSIsIkFEQUgiLCJBREVQIiwiQUVIRSIsIkFMQyIsIkFPT0EiLCJJUkFEIiwiSVJFQSIsIklSSUYiLCJJUlMiLCJJVFMiLCJQSSIsIlBOIiwiVFAiLCJUVVVBSSIsIlRVVUFOIiwiSVJSIikpDQpgYGANCg0KRmluYWxtZW50ZSwgZWxpbWluYXJlbW9zIGFxdWVsbGFzIG9ic2VydmFjaW9uZXMgZG9uZGUgZXhpc3RhbiBOQSdzLiBBbnRlcyBkZSBoYWNlciBlc3RvIGVuY29udHJhbW9zIHF1ZSBsYSBtYXlvcsOtYSBkZSBhZXJvcHVlcnRvcyBkZSBsYSBpbmZyYWVzdHJ1Y3R1cmEgIkNPUlBBQyBTLkEuIiBubyBoYSByZXBvcnRhZG8gc3VzIGluZ3Jlc29zIHRvdGFsZXMgcG9yIGxvIHRhbnRvIGVzdGFyw61hbW9zIGRlamFuZG8gZnVlcmEgZGVsIGFuw6FsaXNpcyBhIGVzdG9zIGFlcm9wdWVydG9zLg0KDQpgYGB7cn0NCkRGIDwtIGRyb3BfbmEoREYpDQpgYGANCg0KYGBge3J9DQpzdW0oY29tcGxldGUuY2FzZXMoREYpKQ0KYGBgDQoNCiMjIEV4cG9ydGFuZG8gbGEgYmFzZSBkZSBkYXRvcw0KDQpgYGB7cn0NCndyaXRlX2NzdihERiwiQmFzZUxpbXBpYXYyLmNzdiIpDQoNCmBgYA0KDQojIEltcG9ydGFuZG8gbGEgYmFzZSBkYXRvcyBsaW1waWENCg0KYGBge3J9DQoNCnJtKGxpc3QgPSBscygpKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkocGx5cikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkodGlkeXIpDQoNCkRGIDwtIHJlYWRfY3N2KCJCYXNlTGltcGlhdjIuY3N2IikNCmBgYA0KDQojIFZhcmlhYmxlcw0KDQoqKkHDsW86KiogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIGluZGljYSBlbCBhw7FvIGRlIGxhIHJlY29sZWNjacOzbiBkZSBpbmZvcm1hY2nDs24uDQoNCioqTWVzOioqIFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSBpbmRpY2EgZWwgbWVzIGRlIGxhIHJlY29sZWNjacOzbiBkZSBpbmZvcm1hY2nDs24uDQoNCioqQWVyb3B1ZXJ0bzoqKiBWYXJpYWJsZSBjdWFsaXRhdGl2YSBxdWUgaW5kaWNhIGVsIGFlcm9wdWVydG8gZGVsIGN1YWwgc2UgcmVjb2xlY3RhIGxhIGluZm9ybWFjacOzbg0KDQoqKkluZnJhZXN0cnVjdHVyYToqKiBWYXJpYWJsZSBjdWFsaXRhdGl2YSBxdWUgaW5kaWNhIGVuIGFjcsOzbmltbyBhIHF1ZSBlbnRpZGFkIHBlcnRlbmVjZSBsYSBpbmZyYWVzdHJ1Y3R1cmEgZGVsIGFlcm9wdWVydG8gZGVsIGN1YWwgc2UgcmVjb2xlY3RhIGxhIGluZm9ybWFjacOzbi4NCg0KKipJbmZyYWVzdHJ1Y3R1cmE6KiogVmFyaWFibGUgY3VhbGl0YXRpdmEgcXVlIGluZGljYSBhIHF1ZSBlbnRpZGFkIHBlcnRlbmVjZSBsYSBpbmZyYWVzdHJ1Y3R1cmEgZGVsIGFlcm9wdWVydG8gZGVsIGN1YWwgc2UgcmVjb2xlY3RhIGxhIGluZm9ybWFjacOzbi4NCg0KKipJVDoqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZW4gZG9sYXJlcyBxdWUgaGEgcmVnaXN0cmFkbyBlbCBhZXJvcHVlcnRvDQoNCioqSVI6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGxvcyBpbmdyZXNvcyByZWd1bGFkb3MgZW4gZG9sYXJlcyBxdWUgaGEgcmVnaXN0cmFkbyBlbCBhZXJvcHVlcnRvDQoNCioqVFVVQU4qKjogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBxdWUgaGEgZ2VuZXJhZG8gbGEgKlRBUklGQSBVTklGSUNBREEgUE9SIFVTTyBERSBBRVJPUFVFUlRPIGRlIHRpcG8gbmFjaW9uYWwuKg0KDQoqKlRVVUFOKio6IFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgcXVlIGhhIGdlbmVyYWRvIGxhICpUQVJJRkEgVU5JRklDQURBIFBPUiBVU08gREUgQUVST1BVRVJUTyBkZSB0aXBvIGludGVybmFjaW9uYWwuKg0KDQoqKk5QSToqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgbnVtZXJvIGRlIHBhc2FqZXJvcyBpbnRlcm5hY2lvbmFsZXMgcXVlIGhhIHJlZ2lzdHJhZG8gZWwgYWVyb3B1ZXJ0bw0KDQoqKk5QTjoqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgbnVtZXJvIGRlIHBhc2FqZXJvcyBuYWNpb25hbGVzIHF1ZSBoYSByZWdpc3RyYWRvIGVsIGFlcm9wdWVydG8NCg0KKipJUkFEX1ZFUjoqKiBWYXJpYWJsZSBjYXRlZ8OzcmljYSBxdWUgcmVwcmVzZW50YSBzaSBlbCBhZXJvcHVlcnRvIG9idGllbmUgaW5ncmVzb3MgcG9yIGF0ZXJyaXphamUgeSBkZXNwZWd1ZS4NCg0KKipJUkFEOioqIFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBpbmdyZXNvIGVuIGRvbGFyZXMgZGVsIGFlcm9wdWVydG8gcG9yIGF0ZXJyaXphamUgeSBkZXNwZWd1ZS4NCg0KKipBQURNX1ZFUjoqKiBWYXJpYWJsZSBjYXRlZ8OzcmljYSBxdWUgcmVwcmVzZW50YSBzaSBlbCBhZXJvcHVlcnRvIG9idGllbmUgaW5ncmVzb3MgcG9yIGVsIGFscXVpbGVyIGRlIMOhcmVhcyBkZSBtYW50ZW5pbWllbnRvLg0KDQoqKkFBRE06KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgYWxxdWlsZXIgZGUgw6FyZWFzIGRlIG1hbnRlbmltaWVudG8uDQoNCioqQURFUF9WRVI6KiogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBlbCBhbHF1aWxlciBkZSBlc3BhY2lvcyBkZSBwdWJsaWNpZGFkLg0KDQoqKkFERVA6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgYWxxdWlsZXIgZGUgZXNwYWNpb3MgZGUgcHVibGljaWRhZC4NCg0KKipBTENfVkVSOioqIFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgZWwgYWxxdWlsZXIgZGUgbG9jYWxlcyBjb21lcmNpYWxlcy4NCg0KKipBTEM6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgYWxxdWlsZXIgZGUgbG9jYWxlcyBjb21lcmNpYWxlcy4NCg0KKipBT09BX1ZFUjoqKiBWYXJpYWJsZSBjYXRlZ8OzcmljYSBxdWUgcmVwcmVzZW50YSBzaSBlbCBhZXJvcHVlcnRvIG9idGllbmUgaW5ncmVzb3MgcG9yIGVsIGFscXVpbGVyIGRlIG9maWNpbmFzIGRlIG9wZXJhY2lvbmVzIGRlIGFlcm9sw61uZWFzLg0KDQoqKkFPT0E6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgZWwgYWxxdWlsZXIgZGUgb2ZpY2luYXMgZGUgb3BlcmFjaW9uZXMgZGUgYWVyb2zDrW5lYXMuDQoNCioqQURBSF9WRVI6KiogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBlbCBhbHF1aWxlciBkZSBhbG1hY2VuZXMvaGFuZ2FyZXMuDQoNCioqQURBSDoqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciBlbCBhbHF1aWxlciBkZSBhbG1hY2VuZXMvaGFuZ2FyZXMuDQoNCioqQUVIRV9WRVI6KiogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciBsYSBhdGVuY2nDs24gZW4gaG9yYXMgZXh0cmFzLg0KDQoqKkFFSEU6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgbGEgYXRlbmNpw7NuIGVuIGhvcmFzIGV4dHJhcy4NCg0KKipJUkVBX1ZFUjoqKiBWYXJpYWJsZSBjYXRlZ8OzcmljYSBxdWUgcmVwcmVzZW50YSBzaSBlbCBhZXJvcHVlcnRvIG9idGllbmUgaW5ncmVzb3MgcG9yIGVsIGVzdGFjaW9uYW1pZW50byBkZSBhZXJvbmF2ZXMuDQoNCioqSVJFQToqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciBlbCBlc3RhY2lvbmFtaWVudG8gZGUgYWVyb25hdmVzLg0KDQoqKklSSUZfVkVSOioqIFZhcmlhYmxlIGNhdGVnw7NyaWNhIHF1ZSByZXByZXNlbnRhIHNpIGVsIGFlcm9wdWVydG8gb2J0aWVuZSBpbmdyZXNvcyBwb3IgcmVlbWJvbHNvIGVuIGluZ3Jlc29zIGZpbmFuY2llcm9zLg0KDQoqKklSSUY6KiogVmFyaWFibGUgY3VhbnRpdGF0aXZhIHF1ZSByZXByZXNlbnRhIGVsIGluZ3Jlc28gZW4gZG9sYXJlcyBwb3IgcmVlbWJvbHNvIGVuIGluZ3Jlc29zIGZpbmFuY2llcm9zLg0KDQoqKklSUl9WRVI6KiogVmFyaWFibGUgY2F0ZWfDs3JpY2EgcXVlIHJlcHJlc2VudGEgc2kgZWwgYWVyb3B1ZXJ0byBvYnRpZW5lIGluZ3Jlc29zIHBvciByZWVtYm9sc29zLg0KDQoqKklSUjoqKiBWYXJpYWJsZSBjdWFudGl0YXRpdmEgcXVlIHJlcHJlc2VudGEgZWwgaW5ncmVzbyBlbiBkb2xhcmVzIHBvciByZWVtYm9sc29zLg0KDQoqKk5QOioqIFZhcmlhYmxlIGN1YW50aXRhdGl2YSBxdWUgcmVwcmVzZW50YSBlbCBudW1lcm8gZGUgcGFzYWplcm9zIHRvdGFsZXMgcXVlIGhhIHJlZ2lzdHJhZG8gZWwgYWVyb3B1ZXJ0by4NCg0KIyBEZXNjcmlwdG9yZXMgTnVtw6lyaWNvcw0KDQpgYGB7cn0NCmN2IDwtIGZ1bmN0aW9uKHgpew0KICAgIHJldHVybihzZCh4LCBuYS5ybT1UKS9tZWFuKHgsIG5hLnJtPVQpKQ0KfQ0KYGBgDQoNCmBgYHtyfQ0KdGFibGEgPC0gZGF0YS5mcmFtZShWYXJpYWJsZXMgPSBjKCdJVCcsICdOUE4nLCAnTlBJJywgJ1RVVUFOJywnVFVVQUknKSwNCiAgICAgICAgICAgICAgICAgICAgTWVkaWEgPSBjKG1lYW4oREYkSVQsIG5hLnJtPVQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oREYkTlBOLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lYW4oREYkTlBJLCBuYS5ybT0gVCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuKERGJFRVVUFOLCBuYS5ybT0gVCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuKERGJFRVVUFJLCBuYS5ybT0gVCkpLA0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgTWVkaWFuYSA9IGMobWVkaWFuKERGJElULCBuYS5ybT1UKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbihERiROUE4sIG5hLnJtID0gVCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWRpYW4oREYkTlBJLCBuYS5ybT0gVCksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbihERiRUVVVBTiwgbmEucm0gPSBUKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lZGlhbihERiRUVVVBSSwgbmEucm09IFQpKSwgDQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBEZXN2aWFjaW9uID0gYyhzZChERiRJVCwgbmEucm09VCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZChERiROUE4sIG5hLnJtID0gVCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZChERiROUEksIG5hLnJtPSBUKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNkKERGJFRVVUFOLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QoREYkVFVVQUksIG5hLnJtPSBUKSksIA0KICAgICAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgVmFyaWFuemEgPSBjKHZhcihERiRJVCwgbmEucm0gPSBUKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIoREYkTlBOLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcihERiROUEksIG5hLnJtID0gVCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyKERGJFRVVUFOLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhcihERiRUVVVBSSwgbmEucm0gPSBUKSksDQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBSYW5nb0ludGVyY3VhcnRpbCA9IGMoSVFSKERGJElULCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUVIoREYkTlBOLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUVIoREYkTlBJLCBuYS5ybSA9IFQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJUVIoREYkVFVVQU4sIG5hLnJtID0gVCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElRUihERiRUVVVBSSwgbmEucm0gPSBUKSksDQogICAgICAgICAgICAgICAgICAgIA0KICAgICAgICAgICAgICAgICAgICBDb2VmaWNpZW50ZVZhcmlhY2lvbiA9IGMoY3YoREYkSVQpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN2KERGJE5QTiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3YoREYkTlBJKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN2KERGJE5QTiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3YoREYkTlBJKSkpDQp0YWJsYQ0KYGBgDQoNCkRlIGxhIHRhYmxhIHBvZGVtb3MgY29uc2VndWlyIGxhIHNpZ3VpZW50ZSBpbmZvcm1hY2nDs246DQoNCi0gICBMYSBlc2NhbGEgY29uIGxhIHF1ZSBzZSB0cmFiYWphIGVzIGJhc3RhbnRlIGdyYW5kZSwgZGUgYWjDrSBlbCBoZWNobyBxdWUgbGEgdmFyaWFuemEgeSBkZXN2aWFjacOzbiBzZWFuIHRhbiBncmFuZGUuDQoNCi0gICBUYW50byBsYSB2YXJpYW56YSBjb21vIGxhIGRlc3ZpYWNpw7NuIG5vcyBpbmRpY2FuIHF1ZSBsb3MgZGF0b3MgZGUgbG9zIEluZ3Jlc29zIFRvdGFsZXMsIGVsIE51bWVybyBkZSBQYXNhamVyb3MgTmFjaW9uYWxlcyB5IGVsIE51bWVybyBkZSBQYXNhamVyb3MgSW50ZXJuYWNpb25hbGVzIGVzdMOhbiBtdXkgZGlzcGVyc29zLg0KDQotICAgU2UgYXByZWNpYSB1biBmZW7Ds21lbm8gcXVlIGxhIG1lZGlhbmEgeSBlbCByYW5nbyBpbnRlcmN1YXJ0aWwgZGUgbGEgdmFyaWFibGUgUGFzYWplcm9zIGludGVybmFjaW9uYWxlcyBlcyAwLiBFc3RvIHF1aWVyZSBkZWNpciBxdWUgaGF5IG11Y2hvcyBhZXJvcHVlcnRvcyBsb3MgY3VhbGVzIG5vIHN1ZWxlbiByZWNpYmlyIHBhc2FqZXJvcyBpbnRlcm5hY2lvbmFsZXMuDQoNCiMjIE9iamV0aXZvIDENCg0KU2UgcmVhbGl6YXJhIGVsIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiBlbnRyZSBjYWRhIHZhcmlhYmxlIHJ1YnJvIHkgbG9zIGluZ3Jlc29zIHRvdGFsZXMsIGFkZW3DoXMgc2UgY3JlYXLDoSB1biBtb2RlbG8gbGluZWFsIHF1ZSByZXByZXNlbnRlIGxhcyByZWxhY2lvbmVzLiBFc3RvIG5vcyBmYWNpbGl0YSBlbCB0cmFiYWphciBjb24gbGFzIDEyIHZhcmlhYmxlcyB5IHBvZGVyIHNpbnRldGl6YXIgbGEgaW5mb3JtYWNpw7NuIGVuIHVuIHNvbG8gZ3LDoWZpY28uDQoNCmBgYHtyfQ0KY29lZmNvciA8LSBjKDE6MTIpDQoNCiMgVFVVQU4gDQpjb2VmY29yWzFdIDwtY29yKERGJElULCBERiRUVVVBTiwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KDQojIFRVVUFJDQpjb2VmY29yWzJdIDwtY29yKERGJElULCBERiRUVVVBSSwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KDQojIElSQUQNCmNvZWZjb3JbM10gPC1jb3IoREYkSVQsIERGJElSQUQsIHVzZT0iY29tcGxldGUub2JzIikNCg0KDQojIEFBRE0NCmNvZWZjb3JbNF0gPC1jb3IoREYkSVQsIERGJEFBRE0sIHVzZT0iY29tcGxldGUub2JzIikNCg0KIyBBREVQDQpjb2VmY29yWzVdIDwtY29yKERGJElULCBERiRBREVQLCB1c2U9ImNvbXBsZXRlLm9icyIpDQoNCiMgQUxDDQpjb2VmY29yWzZdIDwtY29yKERGJElULCBERiRBTEMsIHVzZT0iY29tcGxldGUub2JzIikNCg0KIyBBT09BDQpjb2VmY29yWzddIDwtY29yKERGJElULCBERiRBT09BLCB1c2U9ImNvbXBsZXRlLm9icyIpDQoNCg0KIyBBREFIDQpjb2VmY29yWzhdIDwtY29yKERGJElULCBERiRBREFILCB1c2U9ImNvbXBsZXRlLm9icyIpDQoNCiMgQUVIRQ0KY29lZmNvcls5XSA8LWNvcihERiRJVCwgREYkQUVIRSwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KDQoNCiMgSVJFQQ0KY29lZmNvclsxMF0gPC1jb3IoREYkSVQsIERGJElSRUEsIHVzZT0iY29tcGxldGUub2JzIikNCg0KIyBJUklGDQpjb2VmY29yWzExXSA8LWNvcihERiRJVCwgREYkSVJJRiwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KDQojIElSUg0KY29lZmNvclsxMl0gPC1jb3IoREYkSVQsIERGJElSUiwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KDQpgYGANCg0KQWhvcmEgc2UgcHJvY2VkZXLDoSBhIGxhIHJldmlzacOzbiBkZSBsb3MgY29lZmljaWVudGVzIGRlIGNvcnJlbGFjacOzbiwgc2kgZXN0b3MgdGllbmVuIHVuIG7Dum1lcm8gbWF5b3IgYSAwLjc1IG8gbWVub3IgYSAtMC43NSBzZSBjb25zaWRlcmFyw6EgcXVlIHRpZW5lbiB1biBtb2RlbG8gbGluZWFsIHbDoWxpZG8uDQoNCmBgYHtyfQ0KY29lZmNvcg0KYGBgDQoNClNlIG9ic2VydmEgcXVlIGxvcyBjb2VmaWNpZW50ZXMgZGUgY29ycmVsYWNpw7NuIGNvbiBpbmRpY2VzICg0LCA1LCA2LCA3LCA4LCA5LCAxMSB5IDEyKSBubyBjdW1wbGVuIGNvbiBlbCBjcml0ZXJpbyByZXF1ZXJpZG8sIGVzIGRlY2lyIG5vIHBvc2VlbiB1bmEgY29ycmVsYWNpw7NuIGxpbmVhbCBjb24gbGEgdmFyaWFibGUgZGUgaW5ncmVzb3MgdG90YWxlcywgZXN0byB0YW1iacOpbiBub3MgaW5kaWNhIHF1ZSBzdXMgZGF0b3Mgc2UgZW5jdWVudHJhbiBtdXkgZGlzcGVyc29zIGVuIGNvbXBhcmFjacOzbiBjb24gbG9zIGRhdG9zIGRlIGxvcyBpbmdyZXNvcyB0b3RhbGVzLg0KDQpBaG9yYSBzZSByZWFsaXphcsOhIHkgZ3JhZmljYXLDoSBsb3MgbW9kZWxvcyBsaW5lYWxlcyBkZSBsYSB2YXJpYWJsZXMgcXVlIHByZXNlbnRhbiBidWVuYSBjb3JyZWxhY2nDs24uIEVzIGltcG9ydGFudGUgbm90YXIgcXVlIGVuIHRvZGFzIGVzdGFzIHNlIHRpZW5lIHVuYSBjb3JyZWxhY2nDs24gcG9zaXRpdmEsIGVzdG8gdGllbmUgc2VudGlkbyBwdWVzIGVudHJlIG3DoXMgZGluZXJvIGhheWEgZGUgYWxnw7puIHJ1YnJvLCBtw6FzIGRpbmVybyBoYWJyw6EgZW4gbG9zIGluZ3Jlc29zIHRvdGFsZXMNCg0KYGBge3J9DQoNCnBlbmRpZW50ZXMgPC0gYygxOjQpDQppbnRlcmNlcHRvcyA8LSBjKDE6NCkNCg0KIyBUVVVBTiANCm1vZGVsbyA8LSBsbShERiRJVCB+IERGJFRVVUFOLCBkYXRhPURGKQ0KcGVuZGllbnRlc1sxXSA8LSBhcy5udW1lcmljKG1vZGVsbyRjb2VmZmljaWVudHNbMl0pDQppbnRlcmNlcHRvc1sxXSA8LSBhcy5udW1lcmljKG1vZGVsbyRjb2VmZmljaWVudHNbMV0pDQoNCg0KIyBUVVVBSQ0KbW9kZWxvIDwtIGxtKERGJElUIH4gREYkVFVVQUksIGRhdGE9REYpDQpwZW5kaWVudGVzWzJdIDwtIGFzLm51bWVyaWMobW9kZWxvJGNvZWZmaWNpZW50c1syXSkNCmludGVyY2VwdG9zWzJdIDwtIGFzLm51bWVyaWMobW9kZWxvJGNvZWZmaWNpZW50c1sxXSkNCg0KDQojIElSQUQNCm1vZGVsbyA8LSBsbShERiRJVCB+IERGJElSQUQsIGRhdGE9REYpDQpwZW5kaWVudGVzWzNdIDwtIGFzLm51bWVyaWMobW9kZWxvJGNvZWZmaWNpZW50c1syXSkNCmludGVyY2VwdG9zWzNdIDwtIGFzLm51bWVyaWMobW9kZWxvJGNvZWZmaWNpZW50c1sxXSkNCg0KIyBJUklGDQptb2RlbG8gPC0gbG0oREYkSVQgfiBERiRJUkVBLCBkYXRhPURGKQ0KcGVuZGllbnRlc1s0XSA8LSBhcy5udW1lcmljKG1vZGVsbyRjb2VmZmljaWVudHNbMl0pDQppbnRlcmNlcHRvc1s0XSA8LSBhcy5udW1lcmljKG1vZGVsbyRjb2VmZmljaWVudHNbMV0pDQoNCmBgYA0KDQpgYGB7cn0NCmZpZyA8LSBwbG90X2x5KERGLCB4ID0gflRVVUFOLCB5ID0gfklULCANCiAgICAgICAgICAgICAgIHR5cGUgPSAic2NhdHRlciIsIA0KICAgICAgICAgICAgICAgbW9kZSA9ICJtYXJrZXJzIiwNCiAgICAgICAgICAgICAgIG5hbWU9IlRVVUFOIiwNCiAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3QoY29sb3IgPSAnI2VmNDc2ZicpDQogICAgICAgICAgICAgICApICU+JQ0KICAgICAgICBhZGRfdHJhY2UoeCA9IH5jKC1pbnRlcmNlcHRvc1sxXS9wZW5kaWVudGVzWzFdLDkwMDAwMDApLCB5ID0gYygwLHBlbmRpZW50ZXNbMV0qOTAwMDAwMCtpbnRlcmNlcHRvc1sxXSksIA0KICAgICAgICAgICAgICAgdHlwZSA9ICJzY2F0dGVyIiwNCiAgICAgICAgICAgICAgIG1vZGUgPSAibGluZXMiLA0KICAgICAgICAgICAgICAgbmFtZT0iVFVVQU4tbW9kZWwiLA0KICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjZWY0NzZmJykNCiAgICAgICAgICAgICAgICkgJT4lDQogICAgICAgIGFkZF90cmFjZShERiwgeCA9IH5UVVVBSSwgeSA9IH5JVCwgDQogICAgICAgICAgICAgICAgICB0eXBlID0gInNjYXR0ZXIiLCANCiAgICAgICAgICAgICAgICAgIG1vZGUgPSAibWFya2VycyIsDQogICAgICAgICAgICAgICAgICBuYW1lPSJUVVVBSSIsDQogICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyNmZmQxNjYnKQ0KICAgICAgICAgICAgICAgICAgKSAlPiUNCiAgICAgICAgYWRkX3RyYWNlKHggPSB+YygtaW50ZXJjZXB0b3NbMl0vcGVuZGllbnRlc1syXSw5MDAwMDAwKSwgeSA9IGMoMCxwZW5kaWVudGVzWzJdKjkwMDAwMDAraW50ZXJjZXB0b3NbMl0pLCANCiAgICAgICAgICAgICAgICAgIHR5cGUgPSAic2NhdHRlciIsIA0KICAgICAgICAgICAgICAgICAgbW9kZSA9ICJsaW5lcyIsDQogICAgICAgICAgICAgICAgICBuYW1lPSJUVVVBSS1tb2RlbCIsDQogICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyNmZmQxNjYnKQ0KICAgICAgICAgICAgICAgICAgKSAlPiUNCiAgICAgICAgYWRkX3RyYWNlKERGLCB4ID0gfklSQUQsIHkgPSB+SVQsIA0KICAgICAgICAgICAgICAgICAgdHlwZSA9ICJzY2F0dGVyIiwgDQogICAgICAgICAgICAgICAgICBtb2RlID0gIm1hcmtlcnMiLA0KICAgICAgICAgICAgICAgICAgbmFtZT0iSVJBRCIsDQogICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyMwNmQ2YTAnKQ0KICAgICAgICAgICAgICAgICAgKSAlPiUNCiAgICAgICAgYWRkX3RyYWNlKHggPSB+YygtaW50ZXJjZXB0b3NbM10vcGVuZGllbnRlc1szXSw5MDAwMDAwKSwgeSA9IGMoMCxwZW5kaWVudGVzWzNdKjkwMDAwMDAraW50ZXJjZXB0b3NbM10pLCANCiAgICAgICAgICAgICAgICAgIHR5cGUgPSAic2NhdHRlciIsIA0KICAgICAgICAgICAgICAgICAgbW9kZSA9ICJsaW5lcyIsDQogICAgICAgICAgICAgICAgICBuYW1lPSJJUkFELW1vZGVsIiwNCiAgICAgICAgICAgICAgICAgIG1hcmtlciA9IGxpc3QoY29sb3IgPSAnIzA2ZDZhMCcpDQogICAgICAgICAgICAgICAgICApICU+JQ0KICAgICAgICBhZGRfdHJhY2UoREYsIHg9IH5JUkVBLCB5ID0gfklULCANCiAgICAgICAgICAgICAgICAgIHR5cGU9InNjYXR0ZXIiLCANCiAgICAgICAgICAgICAgICAgIG1vZGU9Im1hcmtlcnMiLA0KICAgICAgICAgICAgICAgICAgbmFtZT0iSVJFQSIsDQogICAgICAgICAgICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyMxMThhYjInKQ0KICAgICAgICAgICAgICAgICAgKSAlPiUNCiAgICAgICAgYWRkX3RyYWNlKHggPSB+YygtaW50ZXJjZXB0b3NbNF0vcGVuZGllbnRlc1s0XSw5MDAwMDAwKSwgeSA9IGMoMCxwZW5kaWVudGVzWzRdKjkwMDAwMDAraW50ZXJjZXB0b3NbNF0pLCANCiAgICAgICAgICAgICAgICAgIHR5cGU9InNjYXR0ZXIiLCANCiAgICAgICAgICAgICAgICAgIG1vZGU9ImxpbmVzIiwNCiAgICAgICAgICAgICAgICAgIG5hbWU9IklSRUEtbW9kZWwiLA0KICAgICAgICAgICAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjMTE4YWIyJykNCiAgICAgICAgICAgICAgICAgICkgJT4lDQogICAgICAgIGxheW91dCh4YXhpcyA9IGxpc3QoIHRpdGxlID0gIkluZ3Jlc29zIFVTJCIpLA0KICAgICAgICB5YXhpcyA9IGxpc3QoIHRpdGxlID0gIkluZ3Jlc29zIHRvdGFsZXMgVVMkIikpDQoNCg0KZmlnDQogICAgDQpgYGANCg0KVXNhbmRvIGVsIGdyw6FmaWNvIGludGVyYWN0aXZvIHBvZGVtb3MgYWlzbGFyIGNhZGEgdW5vIGRlIGVzdG9zIHJ1YnJvcyB5IHZlciBzdSBjb21wb3J0YW1pZW50byBqdW50byBhIHN1IG1vZGVsby4gQXF1w60gdmVtb3MgY29tbyBlbCBtb2RlbG8gZGUgSVJFQSB0aWVuZSBsYSBtYXlvciBwZW5kaWVudGUgc2lnbmlmaWNhbmRvIHF1ZSBsYSBtYXlvciBwYXJ0ZSBkZSBsb3MgaW5ncmVzb3MgdG90YWxlcyBlbiBwcm9wb3JjacOzbiB2ZW5kcsOtYSBkZSBlc3RlIHJ1YnJvLCBzaW4gZW1iYXJnbywgb2JzZXJ2YW1vcyBxdWUgbGEgZGF0YSBubyBlcyBjb25ncnVlbnRlLCBlbCBtb2RlbG8gbm8gc2UgYXByb3hpbWEgY29ycmVjdGFtZW50ZSBwZXNlIGEgcXVlIHZpbW9zIHF1ZSBvYnR1dm8gdW4gY29lZmljaWVudGUgZGUgY29ycmVsYWNpw7NuIG1heW9yIGEgMC43NS4gQ29uIGVzdG8gc2UgZGVqYSBlbiBldmlkZW5jaWEgcXVlIGVsIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiBsaW5lYWwgbm8gZXMgZWwgw7puaWNvIHF1ZSBkZWJlbW9zIHRvbWFyIGVuIGN1ZW50YSBhbCByZWFsaXphciB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwuIEVudG9uY2VzLCBkZWphbmRvIGRlIGxhZG8gYSBJUkVBLCBzZSBhcHJlY2lhIHF1ZSBsb3MgbW9kZWxvcyB5IGxhIGRhdGEgZGUgVFVVQU4sIFRVVUFJIGUgSVJBRCBzZSBhcHJveGltYW4gYmFzdGFudGUgYmllbiwgc2llbmRvLCBlbCBkZSBtYXlvciBwZW5kaWVudGUsIElSQUQuIFBvciBsbyBxdWUgY29uY2x1aW1vcyBxdWUgbGEgbWF5b3IgcGFydGUgZGUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZGVwZW5kZW4gZGUgbG9zIGluZ3Jlc29zIG9idGVuaWRvcyBwb3IgZWwgaW1wb3J0ZSBkZSBzZXJ2aWNpb3MgZGUgKipBdGVyaXphamUgeSBkZXNwZWd1ZSoqLg0KDQojIyBPYmpldGl2byAyDQoNCmBgYHtyfQ0KDQpwbG90KERGJElSRUEsIERGJElULCB4bGFiID0gIk51bWVybyBkZSBwYXNhamVyb3MgKG1pbGVzKSIsIHlsYWIgPSAiSW5ncmVzb3MgdG90YWxlcyAobWlsbG9uZXMgZGUgVVMkKSIsIGNvbD0iZGFya2dyZWVuIiwgcGNoPSLigKIiKQ0KYWJsaW5lKGE9aW50ZXJjZXB0b3NbNF0sIGI9IHBlbmRpZW50ZXNbNF0pDQoNCg0KYGBgDQoNCmBgYHtyfQ0KcGxvdF9seSh5ID1+IERGJElULCB4ID1+REYkSVJFQSwgdHlwZT0ic2NhdHRlciIpICU+JQ0KICAgIA0KYGBgDQoNCiMjIyBOdW1lcm8gZGUgUGFzYWplcm9zIHZzIEluZ3Jlc29zIFRvdGFsZXMNCg0KYGBge3J9DQpwbG90KERGJE5QLzEwMDAsIERGJElULzEwMDAwMDAsIHhsYWIgPSAiTnVtZXJvIGRlIHBhc2FqZXJvcyAobWlsZXMpIiwgeWxhYiA9ICJJbmdyZXNvcyB0b3RhbGVzIChtaWxsb25lcyBkZSBVUyQpIiwgY29sPSJkYXJrZ3JlZW4iLCBwY2g9IuKAoiIsIHhsaW0gPSBjKDAsMjAwMCkpDQoNCmBgYA0KDQpDb21lbnphbW9zIGNvbXBhcmFuZG8gZWwgbnVtZXJvIGRlIHBhc2FqZXJvcyBlbiBtaWxlcyB0b3RhbGVzLCBzdW1hIGRlIHBhc2FqZXJvcyBpbnRlcm5hY2lvbmFsZXMgeSBuYWNpb25hbGVzLCBjb24gbG9zIGluZ3Jlc29zIHRvdGFsZXMgZGUgY2FkYSBhZXJvcHVlcnRvIGVuIGRldGVybWluYWRvIG1lcyB5IGHDsW8gZW4gbWlsbG9uZXMgZGUgZG9sYXJlcy4gQSBzaW1wbGUgdmlzdGEgc2UgcHVlZGUgdmVyIHVuIGNpZXJ0byB0aXBvIGRlIHJlbGFjacOzbiBsaW5lYWwsIHNpbiBlbWJhcmdvIHRlbmVtb3MgcXVlIGNvbXByb2JhcmxvLiBVc2FyZW1vcyBlbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24geWEgcXVlIGVzdGUgbm8gdG9tYSBlbiBjdWVudGEgbGEgZXNjYWxhIGRlIGxhcyB1bmlkYWRlcywgcGVyZmVjdG8gcGFyYSBudWVzdHJvIGVzdHVkaW8uDQoNCmBgYHtyfQ0KY29yKERGJElULCBERiROUCwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KYGBgDQoNCkNvbiBsYSBpbmZvcm1hY2nDs24gc3VtaW5pc3RyYWRhIGRlbCBjb2VmaWNpZW50ZSBkZSBjb3JyZWxhY2nDs24gc2UgZGVkdWNlIHF1ZSBsYSByZWxhY2nDs24gbGluZWFsIGVudHJlIGVsIG51bWVybyBkZSBwYXNhamVyb3MgeSBsb3MgaW5ncmVzb3MgdG90YWxlcyBlcyBidWVuYSwgY2FzaSBwZXJmZWN0YSB5IGFzY2VuZGVudGUuIEVzIGRlY2lyIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGF1bWVudGFyYW4gZW4gY3VhbnRvIGF1bWVudGUgZWwgbnVtZXJvIGRlIHBhc2FqZXJvcy4NCg0KQWhvcmEgY3JlYXJlbW9zIHVuIG1vZGVsbyBkZSByZWdyZXNpw7NuIGxpbmVhbC4NCg0KYGBge3J9DQoNCm1vZGVsbyA9IGxtKERGJElUIH4gREYkTlAsIGRhdGE9REYpDQptb2RlbG8NCg0KZCA8LSBkYXRhLmZyYW1lKCJYIj1ERiROUC8xMDAwLCAiWSI9REYkSVQvMTAwMDAwMCkNCm1vZGVsbyA9IGxtKGQkWSB+IGQkWCwgZGF0YT1kKQ0KbW9kZWxvDQpgYGANCg0KSGVtb3MgY3JlYWRvIGRvcyBtb2RlbG9zIHF1ZSBlbiByZWFsaWRhZCBzb24gZWwgbWlzbW8gcGVybyBhIGRpZmVyZW50ZXMgZXNjYWxhcy4gRWwgcHJpbWVybyBub3Mgc2lydmUgcGFyYSB1c2FyIGRpcmVjdGFtZW50ZSBlbCBudW1lcm8gZGUgcGFzYWplcm9zIHkgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZW4gZG9sYXJlcy4gRWwgc2VndW5kbyBwYXJhIHVzYXIgZWwgbnVtZXJvIGRlIHBhc2FqZXJvcyBlbiBtaWxlcyB5IGNvbnNlZ3VpciBsb3MgaW5ncmVzb3MgdG90YWxlcyBlbiBtaWxsb25lcyBkZSBkb2xhcmVzLiBBbWJvcyBtb2RlbG9zIG5vcyBwZXJtaXRlbiBhcHJveGltYXIsIHByZWRlY2lyIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGRlIHVuIGFlcm9wdWVydG8gZW4gZGV0ZXJtaW5hZG8gbWVzIHkgYcOxbyB1c2FuZG8gbGEgY2FudGlkYWQgZGUgcGFzYWplcm9zIHRvdGFsZXMgcXVlIGxsZXZvIGVuIGVsIG1pc21vIGxhcHNvIGRlIHRpZW1wby4NCg0KYGBge3J9DQpwbG90KERGJE5QLzEwMDAsIERGJElULzEwMDAwMDAsIHhsYWIgPSAiTnVtZXJvIGRlIHBhc2FqZXJvcyAobWlsZXMpIiwgeWxhYiA9ICJJbmdyZXNvcyB0b3RhbGVzIChtaWxsb25lcyBkZSBVUyQpIiwgY29sPSJkYXJrZ3JlZW4iLCBwY2g9IuKAoiIsIHhsaW0gPSBjKDAsMjAwMCkpDQphYmxpbmUoYT0gLTAuMTQ4OTAsIGI9MC4wMTY0NiwgY29sPSJncmVlbiIpDQpgYGANCg0KIyMjIE51bWVybyBkZSBQYXNhamVyb3MgTmFjaW9uYWxlcyBlIEludGVybmFjaW9uYWxlcyB2cyBJbmdyZXNvcyBUb3RhbGVzDQoNCmBgYHtyfQ0KcGFyKG1mcm93PWMoMSwyKSkNCg0KcGxvdChERiROUE4vMTAwMCwgREYkSVQvMTAwMDAwMCwgeGxhYiA9ICJOdW1lcm8gZGUgcGFzYWplcm9zIG5hY2lvbmFsZXMgKG1pbGVzKSIsIHlsYWIgPSAiSW5ncmVzb3MgdG90YWxlcyAobWlsbG9uZXMgZGUgVVMkKSIsIGNvbD0icmVkIiwgcGNoPSLigKIiKQ0KDQpwbG90KERGJE5QSS8xMDAwLCBERiRJVC8xMDAwMDAwLCB4bGFiID0gIk51bWVybyBkZSBwYXNhamVyb3MgaW50ZXJuYWNpb25hbGVzIChtaWxlcykiLCB5bGFiID0gIkluZ3Jlc29zIHRvdGFsZXMgKG1pbGxvbmVzIGRlIFVTJCkiLCBjb2w9ImJsdWUiLCBwY2g9IuKAoiIpDQpgYGANCg0KQWhvcmEgdmFtb3MgYSBhbmFsaXphciBsYSByZWxhY2nDs24gZGUgbG9zIHRpcG9zIGRlIHBhc2FqZXJvcyBjb24gbG9zIGluZ3Jlc29zIHRvdGFsZXMuIERlIG51ZXZvIHVzYXJlbW9zIGVsIGNvZWZpY2llbnRlIGRlIGNvcnJlbGFjacOzbiB0YW50byBwYXJhIGxvcyBwYXNhamVyb3MgbmFjaW9uYWxlcyBjb21vIGludGVybmFjaW9uYWxlcy4NCg0KYGBge3J9DQpjb3IoREYkSVQsIERGJE5QTiwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KY29yKERGJElULCBERiROUEksIHVzZT0iY29tcGxldGUub2JzIikNCmBgYA0KDQpEZSBsb3MgY29lZmljaWVudGVzIGRhZG9zIHNlIGVuY3VlbnRyYSBxdWU6DQoNCi0gICBBbWJvcyBkZW11ZXN0cmFuIHF1ZSB0YW50byBsb3MgcGFzYWplcm9zIG5hY2lvbmFsZXMgY29tbyBpbnRlcm5hY2lvbmFsZXMgcG9zZWVuIHVuYSBidWVuYSB5IGFzY2VuZGVudGUgcmVsYWNpw7NuIGxpbmVhbCBjb24gbG9zIGluZ3Jlc29zIHRvdGFsZXMuDQotICAgQW1ib3Mgc29uIG1lbm9yZXMgYWwgKipjb3IqKiBkZSBsb3MgcGFzYWplcm9zIHRvdGFsZXMgY29uIGxvcyBpbmdyZXNvcyB0b3RhbGVzLiBJbmRpY2EgcXVlIHNpIHNlIHVzYSBzb2xvIGEgbG9zIHBhc2FqZXJvcyBuYWNpb25hbGVzIG8gc29sbyBhIGxvcyBpbnRlcm5hY2lvbmFsZXMgcGFyYSBhcHJveGltYXIgbG9zIGluZ3Jlc29zIHRvdGFsZXMsIHNlIHRlbmRyw6EgdW5hIHByZWNpc2nDs24gbWVub3IgYSBxdWUgc2kgc2UgdXNhcsOhIGxhIHN1bWEgZGUgYW1ib3MuDQotICAgRWwgKipjb3IqKiBkZSBsb3MgcGFzYWplcm9zIGludGVybmFjaW9uYWxlcyBlcyBsaWdlcmFtZW50ZSBzdXBlcmlvciBhbCBkZSBsb3MgcGFzYWplcm9zIG5hY2lvbmFsZXMsIG1vc3RyYW5kbyBxdWUgc3UgcmVsYWNpw7NuIGxpbmVhbCBjb24gbG9zIGluZ3Jlc29zIHRvdGFsZXMgZXMgbGlnZXJhbWVudGUgbcOhcyBhY29yZGUgcXVlIGxhIHJlbGFjacOzbiBsaW5lYWwgZGUgbG9zIHBhc2FqZXJvcyBuYWNpb25hbGVzLg0KDQpBaG9yYSBjb25zdHJ1eWFtb3MgbG9zIG1vZGVsb3MgZGUgcmVncmVzacOzbiBsaW5lYWwgcGFyYSBjYWRhIHVuby4NCg0KYGBge3J9DQoNCm1vZGVsbyA9IGxtKERGJElUIH4gREYkTlBOLCBkYXRhPURGKQ0KbW9kZWxvDQoNCmQgPC0gZGF0YS5mcmFtZSgiWCI9REYkTlBOLzEwMDAsICJZIj1ERiRJVC8xMDAwMDAwKQ0KbW9kZWxvID0gbG0oZCRZIH4gZCRYLCBkYXRhPWQpDQptb2RlbG8NCg0KbW9kZWxvID0gbG0oREYkSVQgfiBERiROUEksIGRhdGE9REYpDQptb2RlbG8NCg0KZCA8LSBkYXRhLmZyYW1lKCJYIj1ERiROUEkvMTAwMCwgIlkiPURGJElULzEwMDAwMDApDQptb2RlbG8gPSBsbShkJFkgfiBkJFgsIGRhdGE9ZCkNCm1vZGVsbw0KDQpybShkKQ0KYGBgDQoNClZlbW9zIHF1ZSBsb3MgbW9kZWxvcyBkaWZpZXJlbiBlbiB1bmEgY2FudGlkYWQgY29uc2lkZXJhYmxlIGVuIGN1YW50byBhIHN1IHBlbmRpZW50ZSwgc2luIGVtYmFyZ28sIHN1IGludGVyY2VwdG8gZXMgYmFzdGFudGUgc2ltaWxhciwgdmFtb3MgYSBncmFmaWNhciBlc3RvcyBtb2RlbG9zLg0KDQpgYGB7cn0NCnBhcihtZnJvdz1jKDEsMikpDQoNCnBsb3QoREYkTlBOLzEwMDAsIERGJElULzEwMDAwMDAsIHhsYWIgPSAiTnVtZXJvIGRlIHBhc2FqZXJvcyBuYWNpb25hbGVzIChtaWxlcykiLCB5bGFiID0gIkluZ3Jlc29zIHRvdGFsZXMgKG1pbGxvbmVzIGRlIFVTJCkiLCBjb2w9InJlZCIsIHBjaD0i4oCiIikNCmFibGluZShhPSAtMC4zNjAzMywgYj0wLjAyNDUxLCBjb2w9IiNmNzI1ODUiKQ0KDQpwbG90KERGJE5QSS8xMDAwLCBERiRJVC8xMDAwMDAwLCB4bGFiID0gIk51bWVybyBkZSBwYXNhamVyb3MgaW50ZXJuYWNpb25hbGVzIChtaWxlcykiLCB5bGFiID0gIkluZ3Jlc29zIHRvdGFsZXMgKG1pbGxvbmVzIGRlIFVTJCkiLCBjb2w9ImJsdWUiLCBwY2g9IuKAoiIpDQphYmxpbmUoYT0gMC4zMTk5NiwgYj0wLjA0NzcyLCBjb2w9IiMwMDc3YjYiKQ0KYGBgDQoNCiMjIE9iamV0aXZvIDMNCg0KUGFyYSBhdmVyaWd1YXIgY3VhbCBlcyBlbCBhZXJvcHVlcnRvIHF1ZSBtYXlvciB0csOhZmljbyB5IGVsIGFlcm9wdWVydG8gcXVlIG1heW9yZXMgaW5ncmVzb3MgZ2VuZXJhIGVuIGVsIFBlcsO6IGVuIGxvcyBhw7FvcyAoMjAyMCwgMjAyMSB5IDIwMjIpLCBhbmFsaXphcmVtb3MgbGEgZGlzdHJpYnVjacOzbiBkZSBJbmdyZXNvcyBUb3RhbGVzIHBsYW50ZWFuZG8gZ3LDoWZpY29zIHkgcmVsYWNpb25lcy4NCg0KIyMjIEFuYWxpemFuZG8gbGEgZGlzdHJpYnVjacOzbiBkZSBJbmdyZXNvcyBUb3RhbGVzDQoNCmBgYHtyfQ0KcGxvdF9seSh4ID0gfkRGJElULzEwMDAwMDAsDQogICAgICAgIHR5cGU9Imhpc3RvZ3JhbSIsDQogICAgICAgIGNvbG9yID0gfkRGJEluZnJhZXN0cnVjdHVyYSwNCiAgICAgICAgbmJpbnN4ID0gNDANCiAgICAgICAgKSU+JQ0KbGF5b3V0KHlheGlzID0gbGlzdCggdGl0bGUgPSAiRnJlY3VlbmNpYSIgKSwNCiAgICB4YXhpcyA9IGxpc3QoIHRpdGxlID0gIkluZ3Jlc29zIHRvdGFsZXMgKE1pbGxvbmVzIGRlIFVTJCkiLA0KICAgICAgICAgICAgICAgICAgbnRpY2tzID0gMjApKQ0KYGBgDQoNCkdyYWNpYXMgYWwgaGlzdG9ncmFtYSBzZSBkaWNlIHF1ZSBsb3MgZGF0b3MgZGUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgc29uIHRvdGFsbWVudGUgYXNpbcOpdHJpY29zIHkgc2UgZW5jdWVudHJhbiBhY3VtdWxhZG9zIGVuIHVuIGludGVydmFsbyBkZSAwIC0gMC44IG1pbGxvbmVzIGRlIGRvbGFyZXMuIEVzIGRlY2lyIGxhIG1heW9yw61hIGRlIGFlcm9wdWVydG9zIGRldGVybWluYWRvcyBlbiBjaWVydG8gbWVzIHkgY2llcnRvIGHDsW8gcG9zZWUgdW5vcyBpbmdyZXNvcyB0b3RhbGVzIGRlIGVudHJlIDAgeSAwLjggbWlsbG9uZXMgZGUgZG9sYXJlcy4gRXN0byBwdWVkZSBvY3VycmlyIGRlYmlkbyBhIGRhdG9zIGF0w61waWNvcywgY29uc3RydXlhbW9zIHVuIEJveHBsb3QgcGFyYSBxdWUgbm9zIGF5dWRlLg0KDQpgYGB7cn0NCnBsb3RfbHkoREYsIHg9fkRGJElULzEwMDAwMDAsDQogICAgICAgICAgICB0eXBlID0gImJveCIpJT4lDQpsYXlvdXQoDQogICAgeGF4aXMgPSBsaXN0KCB0aXRsZSA9ICJJbmdyZXNvcyB0b3RhbGVzIChNaWxsb25lcyBkZSBVUyQpIikpDQpgYGANCg0KVXNhbmRvIHVuIEJveHBsb3Qgc2ltcGxlIHNlIGNvbXBydWViYSBjb21vIGxvcyBkYXRvcyBkZSBsb3MgaW5ncmVzb3MgdG90YWxlcyBlc3TDoW4gZGVtYXNpYWRvIGRpc3BlcnNvcyBncmFjaWFzIGEgY2llcnRhIGNhbnRpZGFkIGRlIGRhdG9zIGF0w61waWNvcy4gQWhvcmEgZXMgbmVjZXNhcmlvIGF2ZXJpZ3VhciBkZSBkb25kZSBwcm92aWVuZW4gZXN0b3MgZGF0b3MgYXTDrXBpY29zIHkgcXVlIG5vcyBxdWllcmVuIGRlY2lyLiBQYXJhIGVsbG8gY3JlYXJlbW9zIGRpZmVyZW50ZXMgQm94cGxvdHMgYmFzYWRvcyBlbiBtZXNlcywgaW5mcmFlc3RydWN0dXJhcyB5IGFlcm9wdWVydG9zLg0KDQpgYGB7cn0NCnBsb3RfbHkoREYsIHggPSB+SVQvMTAwMDAwMCwgDQogICAgICAgIHkgPSB+TWVzLCANCiAgICAgICAgY29sb3I9IH5NZXMsIA0KICAgICAgICB0eXBlPSJib3giKSAlPiUNCmxheW91dCh5YXhpcyA9IGxpc3QoIHRpdGxlID0gIk1lcyIpLA0KICAgIHhheGlzID0gbGlzdCggdGl0bGUgPSAiSW5ncmVzb3MgdG90YWxlcyAoTWlsbG9uZXMgZGUgVVMkKSIpKQ0KYGBgDQoNCkNvbiBlc3RlIGdyw6FmaWNvIHBvZGVtb3MgZGVzY2FydGFyIHF1ZSBsb3MgZGF0b3MgYXTDrXBpY29zIHByb3ZlbmdhbiBkZSB1biBvIHZhcmlvcyBtZXNlcyBlbiBlc3BlY8OtZmljby4NCg0KYGBge3J9DQpwbG90X2x5KERGLCB4ID0gfklULzEwMDAwMDAsIA0KICAgICAgICB5ID0gfkluZnJhZXN0cnVjdHVyYSwgDQogICAgICAgIGNvbG9yPSB+SW5mcmFlc3RydWN0dXJhLCANCiAgICAgICAgdHlwZT0iYm94IikgJT4lDQpsYXlvdXQoeWF4aXMgPSBsaXN0KCB0aXRsZSA9ICJJbmZyYWVzdHJ1Y3R1cmEiKSwNCiAgICB4YXhpcyA9IGxpc3QoIHRpdGxlID0gIkluZ3Jlc29zIHRvdGFsZXMgKE1pbGxvbmVzIGRlIFVTJCkiKSkNCmBgYA0KDQpFbiBlc3RlIGdyw6FmaWNvIHNlIG9ic2VydmEgY29tbyBMaW1hIEFpcnBvcnQgUGFydG5lcnMgUy5SLkwgcmViYXNhIHBvciBtdWNobyBhIGxhcyBvdHJhcyBpbmZyYWVzdHJ1Y3R1cmFzIGVuIGN1YW50byBhIGluZ3Jlc29zIHRvdGFsZXMgc2UgcmVmaWVyZS4gQXF1w60gcG9kZW1vcyB5YSBzYWJlciBxdWUgZXNvcyBkYXRvcyBhdMOtcGljb3MgZGUgaW5ncmVzb3MgZXN0w6FuIGdlbmVyYWRvcyBlbiBzdSBncmFuIG1heW9yw61hIHBvciBsYSBpbmZyYWVzdHJ1Y3R1cmEgTGltYSBBaXJwb3J0IFBhcnRuZXJzIFMuUi5MLiBBZGVtw6FzIGVzIGltcG9ydGFudGUgbWVuY2lvbmFyIHF1ZSBsYSBpbmZyYWVzdHJ1Y3R1cmEgQ09SIG5vIGFwYXJlY2UgZW4gbGEgZ3LDoWZpY2EgcHVlcyBubyBoYSBkZWNsYXJhZG8gbmluZ8O6biBpbmdyZXNvIHRvdGFsLg0KDQpPdHJvcyBkYXRvcyBhIGNvbnNpZGVyYXI6DQoNCi0gRWwgYm94cGxvdCBkZSBMaW1hIEFpcnBvcnQgUGFydG5lcnMgUy5SLkwgc2UgdmUgcGVyZmVjdG8gY3VhbmRvIGxvIGFpc2xhbW9zLCBtdWVzdHJhIHF1ZSBubyBwb3NlZSBuaW5nw7puIGRhdG8gYXTDrXBpY28uDQoNCi0gRWwgYm94cGxvdCBkZSBBZXJvcHVlcnRvcyBkZWwgUGVyw7ogUy5BIGFsIGFpc2xhcmxvIHNlIG9ic2VydmEgY29tbyBsYSBjYWphIGVzIGJhc3RhbnRlIHBlcXVlw7FhIHkgcG9zZWUgbXVjaG9zIGRhdG9zIGF0w61waWNvcyBxdWUgc29uIG1heW9yZXMgYSBsYSBtZWRpYW5hLg0KDQotIEVsIGJveHBsb3QgZGUgQWVyb3B1ZXJ0b3MgQW5kaW5vcyBkZWwgUGVyw7ogUy5BIG11ZXN0cmEgdW4gYmlnb3RlIHBlZ2FkbyBhbCBjdWFydGlsIDI1JSwgZGVtb3N0cmFuZG8gcXVlIGxvcyBkYXRvcyBkZWwgMjUlIGluZmVyaW9yIHNvbiBpZ3VhbGVzIG8gbXV5IGNlcmNhbm9zLiBBc2ltaXNtbyBzZSBvYnNlcnZhbiBkYXRvcyBhdGlwaWNvcyBtYXlvcmVzIGEgbGEgbWVkaWFuYS4NCg0KYGBge3J9DQpwbG90X2x5KERGLCB4ID0gfklULzEwMDAwMDAsIA0KICAgICAgICB5ID0gfkFlcm9wdWVydG8sIA0KICAgICAgICBjb2xvcj0gfkFlcm9wdWVydG8sIA0KICAgICAgICB0eXBlPSJib3giDQogICAgICAgICkgJT4lDQpsYXlvdXQoeWF4aXMgPSBsaXN0KCB0aXRsZSA9ICJBZXJvcHVlcnRvcyIpLA0KICAgIHhheGlzID0gbGlzdCggdGl0bGUgPSAiSW5ncmVzb3MgdG90YWxlcyAoTWlsbG9uZXMgZGUgVVMkKSIpKQ0KYGBgDQoNCkdyYWNpYXMgYSBsb3MgMyBncsOhZmljb3MgcG9kZW1vcyBjb25jbHVpciBxdWU6DQoNCi0gICBFbCBhZXJvcHVlcnRvIGRlIExpbWEgY3V5YSBlbnRpZGFkIHByZXN0YWRvcmEgZXMgbGEgTEFQLCBlcyBsYSByZXNwb25zYWJsZSBkZSBsb3MgZGF0b3MgYXTDrXBpY29zIHkgYWRlbcOhcyBlcyBlbCBxdWUgbcOhcyBpbmdyZXNvcyB0b3RhbGVzIGdlbmVyYS4NCg0KLSAgIEVsIGJveHBsb3QgZGVsIGFlcm9wdWVydG8gTGltYSBhaXNsYWRvIGVuIGJhc2UgYSBsb3MgaW5ncmVzb3MgdG90YWxlcyBtdWVzdHJhIHF1ZSBleGlzdGUgZGF0b3MgbWVub3JlcyBhIGxhIG1lZGlhbmEgbcOhcyBzaW4gZW1iYXJnbyBzdSBtaW5pbW8gc2UgYXByw7N4aW1hIHBvciBtdWNobyBhbCBxdWFydGlsIGluZmVyaW9yIDI1JS4gICANCg0KLSAgIExhIGluZnJhZXN0cnVjdHVyYSBMQVAgdHJhYmFqYSBlbiBMaW1hIHkgc2UgcmVmaWVyZSBhbCBBZXJvcHVlcnRvIEludGVybmFjaW9uYWwgSm9yZ2UgQ2jDoXZlei4gRXN0byBub3MgcXVpZXJlIGRlY2lyIHF1ZSBlbiBlbCBQZXLDuiwgZWwgYWVyb3B1ZXJ0byBxdWUgZ2VuZXJhIG3DoXMgaW5ncmVzb3MgZXMgZWwgSm9yZ2UgQ2jDoXZlei4NCg0KIyMjIE51bWVybyBkZSBQYXNhamVyb3MgdnMgQWVyb3B1ZXJ0b3MNCg0KYGBge3J9DQpwbG90X2x5KERGLHkgPSB+TlAvMTAwMCwNCiAgICAgICAgeCA9IH5hcy5mYWN0b3IoQWVyb3B1ZXJ0byksIA0KICAgICAgICB0eXBlPSJiYXIiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yPWMoImxpZ2h0Ymx1ZSIpKQ0KICAgICAgICApJT4lDQogICAgbGF5b3V0KHhheGlzID0gbGlzdCggdGl0bGUgPSAiQWVyb3B1ZXJ0b3MiKSwNCiAgICB5YXhpcyA9IGxpc3QoIHRpdGxlID0gIk51bWVybyBkZSBwYXNhamVyb3MgKG1pbGVzKSIpKQ0KYGBgDQoNCkNvbiBlc3RhIGdyw6FmaWNvIHNlIGNvcnJvYm9yYSBxdWUgZWwgQWVyb3B1ZXJ0byBkZSBMaW1hIChBZXJvcHVlcnRvIEludGVybmFjaW9uYWwgSm9yZ2UgQ2jDoXZleikgZ2VuZXJhIGxhIG1heW9yIGNhbnRpZGFkIGRlIGluZ3Jlc29zIHkgYWRlbcOhcyByZWNpYmUgYSBsYSBtYXlvciBjYW50aWRhZCBkZSBwYXNhamVyb3MgcmVzcGVjdG8gYWwgcmVzdG8gZGVsIFBlcsO6LiBPdHJvcyBhZXJvcHVlcnRvcyBub3RhYmxlcyBzb24gQ3VzY28sIEFyZXF1aXBhIGUgSXF1aXRvcyBkb25kZSBDdXNjbyBlcyBlbCBxdWUgbcOhcyBwYXNhamVyb3MgcmVjaWJlIGZ1ZXJhIGRlIExpbWEuIFNlIHByb2NlZGUgYSBkaWJ1amFyIGVsIG51bWVybyBkZSBwYXNhamVyb3MsIGxvcyBpbmdyZXNvcyB0b3RhbGVzIHkgbG9zIGFlcm9wdWVydG9zLg0KDQpgYGB7cn0NCnBsb3RfbHkoREYseCA9IH5OUC8xMDAwLA0KICAgICAgICB5ID0gfklULzEwMDAwMDAsIA0KICAgICAgICB0eXBlPSJzY2F0dGVyIiwNCiAgICAgICAgY29sb3IgPSB+YXMuZmFjdG9yKEFlcm9wdWVydG8pDQogICAgICAgICkNCmBgYA0KDQpFbCBncsOhZmljbyBub3MgZGVqYSBlbiBjbGFybyBsYSBlc3RyZWNoYSByZWxhY2nDs24gZGUgbGEgY2FudGlkYWQgZGUgcGFzYWplcm9zIGNvbiBsYSBkZSBpbmdyZXNvcyBxdWUgcG9zZWUgZWwgYWVyb3B1ZXJ0byBkZSBMaW1hIHkgY29tbyBlc3RlIHNvYnJlc2FsZSBwb3IgbXVjaG8gZGVsIHJlc3RvIGRlIGFlcm9wdWVydG9zLiBTZSBjb25jbHV5ZSBxdWUgbG9zIGRhdG9zIGF0w61waWNvcyBwcm92ZW5pZW50ZXMgZGUgaW5ncmVzb3MgdG90YWxlcyBlcmFuIHkgbm9zIGNvbnRhYmFuIHNvYnJlIGxhcyBwZWN1bGlhcmlkYWRlcyBkZWwgY2FzbyBMaW1hLg0KDQojIyMgSW5ncmVzb3MgVCBVIFUgQSBUb3RhbCB2cyBJbmdyZXNvcyBUb3RhbGVzDQoNClNlIGVsaWdpw7MgbGEgY29tcGFyYWNpw7NuIGRlIGxhcyBUIFUgVSBBLCBwb3JxdWUgZXN0YSBlcyBsYSBUQVJJRkEgVU5JRklDQURBIFBPUiBVU08gREUgQUVST1BVRVJUTywgZXMgZGVjaXIgZXMgdW5hIHRhcmlmYSBxdWUgY29tbyBjb25zdW1pZG9yZXMgZGViZW1vcyBkZSBwYWdhci4gRWwgb2JqZXRpdm8gYXF1w60gZXMgYW5hbGl6YXIgY3VhbnRvIGRlIGxvcyBpbmdyZXNvcyB0b3RhbGVzIHByb3ZpZW5lbiBkaXJlY3RhbWVudGUgZGUgbG9zIGJvbHNpbGxvcyBkZSBsb3MgcGFzYWplcm9zLg0KDQpgYGB7cn0NCnBsb3QoKERGJFRVVUFOLzEwMDAwMDAgKyBERiRUVVVBSS8xMDAwMDAwKSwgREYkSVQvMTAwMDAwMCwgeGxhYiA9ICJJbmdyZXNvcyBUVVVBIChtaWxsb25lcyBkZSBVUyQpIiwgeWxhYiA9ICJJbmdyZXNvcyB0b3RhbGVzIChtaWxsb25lcyBkZSBVUyQpIiwgY29sPSIjOTI2YzE1IiwgcGNoPSLigKIiKQ0KDQpgYGANCg0KQ29tZW56YW1vcyBjb21wYXJhbmRvIGVsIG51bWVybyBkZSBwYXNhamVyb3MgZW4gbWlsZXMgdG90YWxlcywgc3VtYSBkZSBwYXNhamVyb3MgaW50ZXJuYWNpb25hbGVzIHkgbmFjaW9uYWxlcywgY29uIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGRlIGNhZGEgYWVyb3B1ZXJ0byBlbiBkZXRlcm1pbmFkbyBtZXMgeSBhw7FvIGVuIG1pbGxvbmVzIGRlIGRvbGFyZXMuIEEgc2ltcGxlIHZpc3RhIHNlIHB1ZWRlIHZlciB1biBjaWVydG8gdGlwbyBkZSByZWxhY2nDs24gbGluZWFsLCBzaW4gZW1iYXJnbyB0ZW5lbW9zIHF1ZSBjb21wcm9iYXJsby4gVXNhcmVtb3MgZWwgY29lZmljaWVudGUgZGUgY29ycmVsYWNpw7NuIHlhIHF1ZSBlc3RlIG5vIHRvbWEgZW4gY3VlbnRhIGxhIGVzY2FsYSBkZSBsYXMgdW5pZGFkZXMsIHBlcmZlY3RvIHBhcmEgbnVlc3RybyBlc3R1ZGlvLg0KDQpgYGB7cn0NCmNvcihERiRJVCwgREYkVFVVQUkgKyBERiRUVVVBTiwgdXNlPSJjb21wbGV0ZS5vYnMiKQ0KYGBgDQoNClRlbmVtb3MgdW4gY29lZmljaWVudGUgZGUgY29ycmVsYWNpw7NuIHF1ZSBlc3RhIG11eSBwcsOzeGltbyBhIDEsIGVzIGRlY2lyIGVzdGEgcmVsYWNpw7NuIGVzIGNhc2kgcGVyZmVjdGFtZW50ZSBsaW5lYWwgeSBjb24gdGVuZGVuY2lhIGFzY2VuZGVudGUuDQoNCkFob3JhIGNyZWFyZW1vcyB1biBtb2RlbG8gZGUgcmVncmVzacOzbiBsaW5lYWwuDQoNCmBgYHtyfQ0KVFVVQSA8LSBERiRUVVVBSStERiRUVVVBTg0KbW9kZWxvID0gbG0oREYkSVQgfiBUVVVBLCBkYXRhPURGKQ0KbW9kZWxvDQoNCmQgPC0gZGF0YS5mcmFtZSgiWCI9IChERiRUVVVBSSArIERGJFRVVUFOKS8xMDAwMDAsICJZIj1ERiRJVC8xMDAwMDAwKQ0KbW9kZWxvID0gbG0oZCRZIH4gZCRYLCBkYXRhPWQpDQptb2RlbG8NCg0Kcm0oZCkNCmBgYA0KDQpEZWwgbW9kZWxvIGNyZWFkbyBzZSBvYnRpZW5lIGVsIGludGVyY2VwdG8sIGVzIGRlY2lyIGN1YW5kbyBsYSBUVVVBIHZhbGRyw6EgY2VybyB5IGxhIHBlbmRpZW50ZSwgZW4gZXN0ZSBjYXNvIGVzIHJlbGF0aXZhbWVudGUgYmFqYSBwZXJvIGFzY2VuZGVudGUuDQoNCmBgYHtyfQ0KcGxvdCgoREYkVFVVQU4rREYkVFVVQUkpLzEwMDAwMCwgREYkSVQvMTAwMDAwMCwgeGxhYiA9ICJJbmdyZXNvcyBUVVVBIHRvdGFsIChtaWxsb25lcyBkZSBVUyQpIiwgeWxhYiA9ICJJbmdyZXNvcyB0b3RhbGVzIChtaWxsb25lcyBkZSBVUyQpIiwgY29sPSIjOTI2YzE1IiwgcGNoPSLigKIiKQ0KYWJsaW5lKGE9IDAuMTU1NywgYj0wLjIxOTAsIGNvbD0iI2M5YTIyNyIpDQpgYGANCg0KRGV0YWxsYW1vcyBlbnRvbmNlcyBxdWUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZ3VhcmRhbiB1bmEgYWx0YSByZWxhY2nDs24gY29uIGxvcyBpbmdyZXNvcyBnZW5lcmFkb3MgcG9yIGxhcyBUVVVBIHkgZGVwZW5kZW4gZW4gZ3JhbiBtZWRpZGEgZGUgZXN0YXMsIGVyZ28gbGEgY2FudGlkYWQgZGUgcGFzYWplcm9zLg0KDQojIyBPYmpldGl2byA0DQoNCkFob3JhIGhhcmVtb3MgdW4gYW7DoWxpc2lzIGRlIGxhIHBhbmRlbWlhIHkgcG9zdHBhbmRlbWlhIGRlIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGVuIGxvcyBhZXJvcHVlcnRvcyBkZWwgUGVyw7ogZW4gbG9zIGHDsW9zICgyMDIwLDIwMjEgeSAyMDIyKQ0KDQojIyMgUGFuZGVtaWEgdnMgUG9zdFBhbmRlbWlhDQoNCmBgYHtyfQ0KREYyMDIwIDwtIGZpbHRlcihERiwgREYkQcOxbz09IjIwMjAiKQ0KREYyMDIxIDwtIGZpbHRlcihERiwgREYkQcOxbz09IjIwMjEiKQ0KREYyMDIyIDwtIGZpbHRlcihERiwgREYkQcOxbz09IjIwMjIiKQ0KDQpERjIwMjAgJT4lIGdyb3VwX2J5KE1lcyxBw7FvKSAlPiUgc3VtbWFyaXNlKElUID0gc3VtKElULCBuYS5ybT1UUlVFKSwgTlAgPSBzdW0oTlAsIG5hLnJtID0gVFJVRSkpIC0+IERGMjAyMA0KDQpERjIwMjEgJT4lIGdyb3VwX2J5KE1lcyxBw7FvKSAlPiUgc3VtbWFyaXNlKElUID0gc3VtKElULCBuYS5ybT1UUlVFKSwgTlAgPSBzdW0oTlAsIG5hLnJtID0gVFJVRSkpIC0+IERGMjAyMQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0KREYyMDIyICU+JSBncm91cF9ieShNZXMsQcOxbykgJT4lIHN1bW1hcmlzZShJVCA9IHN1bShJVCwgbmEucm09VFJVRSksIE5QID0gc3VtKE5QLCBuYS5ybSA9IFRSVUUpKSAtPiBERjIwMjINCg0KDQpgYGANCg0KYGBge3J9DQpwbG90X2x5KHkgPSB+REYyMDIwJElULzEwMDAwMDAsDQogICAgICAgIHggPSB+REYyMDIwJE1lcywgDQogICAgICAgIHR5cGU9ImJhciIsDQogICAgICAgIG5hbWU9IjIwMjAiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyM1N2NjOTknKQ0KICAgICAgICApJT4lIA0KDQogICAgDQogICAgYWRkX3RyYWNlKHkgPSB+REYyMDIxJElULzEwMDAwMDAsDQogICAgICAgIHggPSB+REYyMDIxJE1lcywgDQogICAgICAgIHR5cGU9ImJhciIsDQogICAgICAgIG5hbWU9IjIwMjEiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyMzOGEzYTUnKQ0KICAgICAgICApJT4lDQogICAgDQogICAgDQogICAgYWRkX3RyYWNlKHkgPSB+REYyMDIyJElULzEwMDAwMDAsDQogICAgICAgIHggPSB+REYyMDIyJE1lcywgDQogICAgICAgIHR5cGU9ImJhciIsDQogICAgICAgIG5hbWU9IjIwMjIiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyMyMjU3N2EnKQ0KICAgICAgICApJT4lDQogICAgDQogICAgDQogICAgbGF5b3V0KHhheGlzID0gbGlzdCggdGl0bGUgPSAiTWVzZXMiKSwNCiAgICB5YXhpcyA9IGxpc3QoIHRpdGxlID0gIkluZ3Jlc29zIHRvdGFsZXMgKE1pbGxvbmVzIGRlIFVTJCkiLA0KICAgIG50aWNrcyA9IDEwLA0KICAgIHJhbmdlID0gbGlzdCgwLDQ1KSksDQogICAgDQogICAgYmFybW9kZT0iZ3JvdXAiKQ0KYGBgDQoNCkRlbCBncsOhZmljbyBkZSBiYXJyYXMgcG9kZW1vcyBvYnNlcnZhcjoNCg0KLSAgIExhIGRpc3RyaWJ1Y2nDs24gZGUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZW4gYmFzZSBhIGxvcyBtZXNlcyBkZWwgYcOxby4NCg0KLSAgIEV4aXN0ZSB1bmEgYXNpbWV0cmlhIG5vdGFibGUgZW50cmUgbG9zIGRhdG9zIGVuIGVsIGHDsW8gMjAyMC4gRXN0YSBhc2ltZXRyaWEgc2UgZXhwbGljYSBwb3IgZWwgc3VyZ2ltaWVudG8gZGVsIENvdmlkLTE5LiBMb3MgaW5ncmVzb3MgYmFqYXJvbiBiYXN0YW50ZSBlbiBwcm9wb3JjacOzbiBhIGxhIG1lZGlhLg0KDQotICAgVW4gcGF0csOzbiBkZSBjcmVjaW1pZW50byBzb2JyZSBsb3MgaW5ncmVzb3MgdG90YWxlcyBkZXBlbmRpZW5kbyBkZSBsb3MgbWVzZXMuIEVuIGFsZ3Vub3MgbWVzZXMgbG9zIGluZ3Jlc29zIHRvdGFsZXMgc29uIGVzcGVyYWRvIGEgc2VyIG1heW9yZXMgcXVlIGVuIG90cm9zIG1lc2VzLCB1bm8gZGUgbG9zIGZhY3RvcmVzIHF1ZSBwdWVkZW4gaW5mbHVpciBlbiBlc3RvIHNvbiBsYXMgdmFjYWNpb25lcyBwdWVzIGVzdMOhbiBlc3RyZWNoYW1lbnRlIHJlbGFjaW9uYXMgY29uIGVsIG7Dum1lcm8gZGUgcGFzYWplcm9zIGEgYWJvcmRhciBlbiB1biBhZXJvcHVlcnRvLg0KDQpgYGB7cn0NCg0KcGxvdF9seSgpICU+JQ0KICAgIGFkZF90cmFjZSh5ID0gfkRGMjAyMCRJVC8xMDAwMDAwLA0KICAgICAgICB4ID0gfkRGMjAyMCRNZXMsIA0KICAgICAgICB0eXBlPSJzY2F0dGVyIiwNCiAgICAgICAgbW9kZT0ibGluZXMrbWFya2VycyIsDQogICAgICAgIG5hbWU9IjIwMjAiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyM1N2NjOTknKSwNCiAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnIzU3Y2M5OScpLA0KICAgICAgICBmaWxsID0gInRvbmV4dHkiLA0KICAgICAgICBmaWxsY29sb3IgPSAncmdiYSgxOTcsMjM3LDIxMSwwLjMpJw0KICAgICAgICApJT4lDQogICAgYWRkX3RyYWNlKERGMjAyMSwgeSA9IH5ERjIwMjEkSVQvMTAwMDAwMCwNCiAgICAgICAgeCA9IH5ERjIwMjEkTWVzLCANCiAgICAgICAgdHlwZT0ic2NhdHRlciIsDQogICAgICAgIG1vZGU9ImxpbmVzK21hcmtlcnMiLA0KICAgICAgICBuYW1lPSIyMDIxIiwNCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjMzhhM2E1JyksDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJyMzOGEzYTUnKSwNCiAgICAgICAgZmlsbCA9ICJ0b25leHR5IiwNCiAgICAgICAgZmlsbGNvbG9yID0gJ3JnYmEoMTA2LDE2NiwxNjksMC4zKScNCiAgICAgICAgKSU+JQ0KICAgIGFkZF90cmFjZSh5ID0gfkRGMjAyMiRJVC8xMDAwMDAwLA0KICAgICAgICB4ID0gfkRGMjAyMiRNZXMsIA0KICAgICAgICB0eXBlPSJzY2F0dGVyIiwNCiAgICAgICAgbW9kZT0ibGluZXMrbWFya2VycyIsDQogICAgICAgIG5hbWU9IjIwMjIiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyMyMjU3N2EnKSwNCiAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnIzIyNTc3YScpLA0KICAgICAgICBmaWxsID0gInRvbmV4dHkiLA0KICAgICAgICBmaWxsY29sb3IgPSAncmdiYSg2OCwxMDIsMTIyLDAuMyknDQogICAgICAgICklPiUNCiAgICANCiAgICBsYXlvdXQoeGF4aXMgPSBsaXN0KCB0aXRsZSA9ICJNZXNlcyIpLA0KICAgICAgICAgICB0aXRsZSA9ICJFdm9sdXRpdm8gSW5ncmVzb3MiLA0KICAgIHlheGlzID0gbGlzdCggdGl0bGUgPSAiSW5ncmVzb3MgdG90YWxlcyAoTWlsbG9uZXMgZGUgVVMkKSIsIA0KICAgICAgICAgICAgICAgICAgcmFuZ2UgPSBsaXN0KDAsNDUpKQ0KICAgICkNCg0KYGBgDQoNCmBgYHtyfQ0KcGxvdF9seSgpICU+JQ0KICAgIGFkZF90cmFjZSh5ID0gfkRGMjAyMCROUC8xMDAwLA0KICAgICAgICB4ID0gfkRGMjAyMCRNZXMsIA0KICAgICAgICB0eXBlPSJzY2F0dGVyIiwNCiAgICAgICAgbW9kZT0ibGluZXMrbWFya2VycyIsDQogICAgICAgIG5hbWU9IjIwMjAiLA0KICAgICAgICBtYXJrZXIgPSBsaXN0KGNvbG9yID0gJyNFMDlGM0UnKSwNCiAgICAgICAgbGluZSA9IGxpc3QoY29sb3IgPSAnI0UwOUYzRScpLA0KICAgICAgICBmaWxsID0gInRvbmV4dHkiLA0KICAgICAgICBmaWxsY29sb3IgPSAncmdiYSgyMjUsMTgzLDEyMywwLjMpJw0KICAgICAgICApJT4lDQogICAgYWRkX3RyYWNlKERGMjAyMSwgeSA9IH5ERjIwMjEkTlAvMTAwMCwNCiAgICAgICAgeCA9IH5ERjIwMjEkTWVzLCANCiAgICAgICAgdHlwZT0ic2NhdHRlciIsDQogICAgICAgIG1vZGU9ImxpbmVzK21hcmtlcnMiLA0KICAgICAgICBuYW1lPSIyMDIxIiwNCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjOUUyQTJCJyksDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJyM5RTJBMkInKSwNCiAgICAgICAgZmlsbCA9ICJ0b25leHR5IiwNCiAgICAgICAgZmlsbGNvbG9yID0gJ3JnYmEoMTU4LDcyLDc0LDAuMyknDQogICAgICAgICklPiUNCiAgICBhZGRfdHJhY2UoeSA9IH5ERjIwMjIkTlAvMTAwMCwNCiAgICAgICAgeCA9IH5ERjIwMjIkTWVzLCANCiAgICAgICAgdHlwZT0ic2NhdHRlciIsDQogICAgICAgIG1vZGU9ImxpbmVzK21hcmtlcnMiLA0KICAgICAgICBuYW1lPSIyMDIyIiwNCiAgICAgICAgbWFya2VyID0gbGlzdChjb2xvciA9ICcjNTQwQjBFJyksDQogICAgICAgIGxpbmUgPSBsaXN0KGNvbG9yID0gJyM1NDBCMEUnKSwNCiAgICAgICAgZmlsbCA9ICJ0b25leHR5IiwNCiAgICAgICAgZmlsbGNvbG9yID0gJ3JnYmEoODcsNDUsNDcsMC4zKScNCiAgICAgICAgKSU+JQ0KICAgIA0KICAgIGxheW91dCh4YXhpcyA9IGxpc3QoIHRpdGxlID0gIk1lc2VzIiksDQogICAgICAgICAgIHRpdGxlID0gIkV2b2x1dGl2byBQYXNhamVyb3MiLA0KICAgIHlheGlzID0gbGlzdCggdGl0bGUgPSAiTnVtZXJvIGRlIFBhc2FqZXJvcyAoTWlsZXMpIikpDQpgYGANCg0KRGUgbG9zIGdyw6FmaWNvcyBldm9sdXRpdm9zIHBvZGVtb3MgYXByZWNpYXI6DQoNCi0gICBDb21vIGVzIGVsIGNvbXBvcnRhbWllbnRvIGRlIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGZyZW50ZSBhIGxvcyBtZXNlcyB5IGEgbG9zIGHDsW9zIG1hcmNhZG9zIHBvciBsYSBwYW5kZW1pYS4NCg0KLSAgIEVuIGVsIG1lcyBkZSBGZWJyZXJvIGRlbCBhw7FvIDIwMjAgY29taWVuemEgdW5hIGNhw61kYSBkcsOhc3RpY2EgZW4gbG9zIGluZ3Jlc29zIGhhc3RhIEFicmlsIGRlbCBtaXNtbyBhw7FvIGRvbmRlIGNvbWllbnphIGEgZXN0YWJpbGl6YXJzZS4gRXN0ZSBwZXJpb2RvIGNvaW5jaWRlIGNvbiBsYSBhcGFyaWNpw7NuIGRlbCBDb3ZpZC0xOSBlbiBQZXLDuiB5IGVsIGVzdGFibGVjaW1pZW50byBkZSBsYXMgbWVkaWRhcyBkZSBjb25maW5hbWllbnRvLiBFbCBjb25maW5hbWllbnRvIGluZGljYSBxdWUgZWwgbsO6bWVybyBkZSBwYXNhamVyb3Mgc2UgcmVkdWNlIGVuIGdyYW4gcHJvcG9yY2nDs24uIEVzdGEgY2F1c2EgdGFtYmnDqW4gc2UgcHVlZGUgb2JzZXJ2YXIgZW4gZWwgZXZvbHV0aXZvIGRlIHBhc2FqZXJvcyB5IGVsIGNvbW8gc3UgbsO6bWVybyBkZSBjYWUgaGFzdGEgMCBvIGNhc2kgMC4gTG9zIGFlcm9wdWVydG8gdHV2aWVyb24gY29uc2VjdWVuY2lhcyBxdWUgdGFyZGFyb24gbXVjaG8gZW4gZGlzaXBhcnNlIE11ZXN0cmEgZGUgZWxsbyBlcyBjb21vIHNlIHRhcmTDsyAyIGHDsW9zIHkgNSBtZXNlcyBwYXJhIHZvbHZlciBhIHVuIHB1bnRvIHNpbWlsYXIgYWwgZGUgRmVicmVybyAyMDIwIGVuIGluZ3Jlc29zIHRvdGFsZXMuDQoNCg0KICAgIGBgYHtyfQ0KDQogICAgcm91bmQoMTAwIC0gKChmaWx0ZXIoREYyMDIwLCBNZXMgPT0gIkFicmlsIikkSVQvMTAwMDAwMCApLyggZmlsdGVyKERGMjAyMCwgTWVzID09ICJGZWJyZXJvIikkSVQvMTAwMDAwMCkgKiAxMDApICwyKQ0KDQogICAgcm91bmQoIC0gZmlsdGVyKERGMjAyMCwgTWVzID09ICJBYnJpbCIpJElULzEwMDAwMDAgICsgZmlsdGVyKERGMjAyMCxNZXMgPT0gIkZlYnJlcm8iKSRJVC8xMDAwMDAwLCAyKQ0KICAgIGBgYA0KDQotICAgTGEgcMOpcmRpZGEgZGVsIG1lcyBkZSBBYnJpbCBkZWwgMjAyMCByZXNwZWN0byBhbCBtZXMgZGUgRmVicmVybyBkZWwgMjAyMCBmdWUgZGVsIDg2LjY4JSBzdXBvbmllbmRvIHVuYSBkaWZlcmVuY2lhIGRlIDMxLjc2IG1pbGxvbmVzIGRlIGRvbGFyZXMuDQoNCi0gICBBIHBhcnRpciBkZWwgbWVzIGRlIEFicmlsIHNlIGVzdGFiaWxpemFuIGxvcyBpbmdyZXNvcyBkZWwgYcOxbyAyMDIwLiBFc3RvcyBzb24gYmFqb3MgcGVybyBzZSBvYnNlcnZhIHVuYSB0ZW5kZW5jaWEgYXNjZW5kZW50ZS4gVGVuZGVuY2lhIHF1ZSBjb250aW51YSBlbiBsb3MgYcOxb3MgMjAyMSB5IDIwMjIgYSBtZWRpZGEgcXVlIGVsIGNvbmZpbmFtaWVudG8gc2UgbGV2YW50YSwgbGEgcGFuZGVtaWEgc2UgY29udHJvbGEgeSBlbCBudW1lcm8gZGUgcGFzYWplcm9zIGF1bWVudGEuDQoNCg0KIyMgQ29uY2x1c2nDs24NCg0KQSByYXrDs24gZGUgcmVzdW1lbiwgZW4gbnVlc3RybyBhbsOhbGlzaXMgc29icmUgbG9zIGZhY3RvcmVzIGluZmx1eWVudGVzIGVuIGxvcyBpbmdyZXNvcyB0b3RhbGVzIGRlIGxvcyBhZXJvcHVlcnRvcyBzZSBncsOhZmljbyBsYSBkaXN0cmlidWNpw7NuIGRlIGxvcyBpbmdyZXNvcyB0b3RhbGVzLCBsYXMgZGlmZXJlbnRlcyByZWxhY2lvbmVzIGVudHJlIHZhcmlhYmxlcyB0YWxlcyBjb21vIGxhIMO6bHRpbWEgdmlzdGEgKEluZ3Jlc29zIFRVVUEgdnMgSW5ncmVzb3MgVG90YWxlcyksIChjYW50aWRhZCBkZSBwYXNhamVyb3MgeSBhZXJvcHVlcnRvcykuIEFzaW1pc21vIG9ic2VydmFtb3MgeSBkZXNjcmliaW1vcyBlbCBjb21wb3J0YW1pZW50byBldm9sdXRpdm8gZGUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgcmVzcGVjdG8gYSBsb3MgYcOxb3Mgdml2aWRvcyBlbiBwYW5kZW1pYSB5IHBvcy1wYW5kZW1pYS4gRmluYWxtZW50ZSwgY29uIGxhIGluZm9ybWFjacOzbiByZWNvbGVjdGFkYSB5IGVsIGVzdHVkaW8gcmVhbGl6YWRvIHNlIGVuY29udHLDsyBxdWUgbG9zIGluZ3Jlc29zIHRvdGFsZXMgZ2VuZXJhZG9zIHBvciBsb3MgYWVyb3B1ZXJ0b3MgZW4gZWwgUGVyw7ogZGVwZW5kZW4gYWx0YW1lbnRlIGVuIGxvcyBjb25zdW1pZG9yZXMgbyBwYXNhamVyb3MsIHNpZW5kbyBsYSBUVVVBIHkgZWwgSVJBRCBsb3MgZWplbXBsb3MgbcOhcyBjbGFyb3MgZGUgZWxsby4NCg0KIyBSZWZlcmVuY2lhcw0KDQpHYWJyaWVsIFVURUM6IE9TSVRSQU4gREFUQS4gKHMvZikuIEdvYi5wZTo4NDQzLiBSZWN1cGVyYWRvIGVsIDE3IGRlIGFicmlsIGRlIDIwMjMsIGRlIGh0dHBzOi8vc2VydmljaW9zZGlnaXRhbGVzLm9zaXRyYW4uZ29iLnBlOjg0NDMvUG9ydGFsRGF0b3NPc2l0cmFuL2luaWNpby5qc3ANCg0KDQpNZXphIEp1w6FyZXosIFYuIEEuICgyMDIwKS4gQVBBVklUIHkgdHVyaXNtbyBzZWd1cm8gcG9zdCBwYW5kZW1pYSBkZWwgQ292aWQtMTkgW1RyYWJham8gZGUgc3VmaWNpZW5jaWEgcHJvZmVzaW9uYWwgcGFyYSBvcHRhciBlbCBUw610dWxvIFByb2Zlc2lvbmFsIGRlIExpY2VuY2lhZG8gZW4gQ29tdW5pY2FjacOzbiwgVW5pdmVyc2lkYWQgZGUgTGltYV0uIFJlcG9zaXRvcmlvIEluc3RpdHVjaW9uYWwuIGh0dHBzOi8vaGRsLmhhbmRsZS5uZXQvMjAuNTAwLjEyNzI0LzExODEwDQoNCg0KQ3ViaWxsb3MsIEcuLCAmIEFsZWphbmRyYSwgTS4gKDIwMjIpLiBBbsOhbGlzaXMgZGUgbGEgQXBlcnR1cmEgZGUgbGEgRWNvbm9tw61hIFBvc3QgUGFuZGVtaWEgZW4gbG9zIFBhw61zZXMgTWllbWJyb3MgZGUgbGEgQWxpYW56YSBkZWwgUGFjw61maWNvICgyMDIwLTIwMjEpLiBodHRwOi8vcmVwb3NpdG9yeS51bmlwaWxvdG8uZWR1LmNvL2hhbmRsZS8yMC41MDAuMTIyNzcvMTE5ODANCg0KDQpWLiwgQ2FzdHJvIFPDoW5jaGV6LCBGLiwgJiBSb21lcm8gRmVybsOhbmRleiwgQS4gUi4gRi4gKDIwMjApLiBJbXBhY3RvIGRlIGxhIENPVklELTE5IGVuIGVsIHR1cmlzbW8gbXVuZGlhbCAoSW1wYWN0IG9mIENPVklELTE5IG9uIFdvcmxkIFRvdXJpc20pLiBodHRwczovL3BhcGVycy5zc3JuLmNvbS9hYnN0cmFjdD0zODE4Njg1